/
Thread.pod6
165 lines (104 loc) · 4.77 KB
/
Thread.pod6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
=begin pod
=TITLE class Thread
=SUBTITLE Concurrent execution of code (low-level)
class Thread {}
A L<thread|https://en.wikipedia.org/wiki/Thread_%28computing%29> is a sequence
of instructions that can (potentially) run in parallel to others. Class
C<Thread> provides a bit of abstraction over threads provided by the
underlying virtual machines (which in turn might or might not be operating
system threads).
Since threads are fairly low-level, most applications should use other
primitives, like L<start|/type/Promise#method start>, which also runs in
parallel and returns a L<Promise|/type/Promise>.
=begin code
use v6.c;
my @threads = (^10).map: {
Thread.start(
name => "Sleepsorter $_",
sub {
my $rand = (^10).pick;
sleep $rand;
say $rand;
},
);
}
.finish for @threads;
=end code
The current thread is available in the dynamic variable C<$*THREAD>.
=head1 Methods
=head2 method new
method new(:&code!, Bool :$app_lifetime = False, Str :$name = '<anon>' --> Thread:D)
Creates and returns a new C<Thread>, without starting it yet. C<&code> is the
code that will be run in a separate thread.
C<$name> is a user-specified string that identifies the thread.
If C<$app_lifetime> is set to C<True>, then the thread is killed when the main
thread of the process terminates. If set to C<False>, the process will only
terminate when the thread has finished.
=head2 method start
method start(Thread:U: &code, Bool :$app_lifetime = False, Str :$name = '<anon>' --> Thread:D)
Creates, runs and returns a new C<Thread>. Note that it can (and often does)
return before the thread's code has finished running.
=head2 method run
method run(Thread:D:)
Runs the thread, and returns the invocant. It is an error to run a thread that
has already been started.
=head2 method id
method id(Thread:D: --> Int:D)
Returns a numeric, unique thread identifier.
=head2 method finish
method finish(Thread:D)
Waits for the thread to finish. This is called L<join|#method_join> in other programming
systems.
=head2 method join
method join(Thread:D)
Waits for the thread to finish.
=head2 method yield
method yield(Thread:U)
Tells the scheduler to prefer another thread for now.
Thread.yield;
=head2 method app_lifetime
method app_lifetime(Thread:D: --> Bool:D)
Returns C<False> unless the named parameter C<:app_lifetime> is specifically set
to C<True> during object creation. If the method returns C<False> it means that
the process will only terminate when the thread has finished while C<True> means that
the thread will be killed when the main thread of the process terminates.
my $t1 = Thread.new(code => { for 1..5 -> $v { say $v }});
my $t2 = Thread.new(code => { for 1..5 -> $v { say $v }}, :app_lifetime);
say $t1.app_lifetime; # OUTPUT: «False»
say $t2.app_lifetime; # OUTPUT: «True»
=head2 method name
method name(Thread:D: --> Str:D)
Returns the user defined string, which can optionally be set during object
creation in order to identify the C<Thread>, or '<anon>' if no such string
was specified.
my $t1 = Thread.new(code => { for 1..5 -> $v { say $v }});
my $t2 = Thread.new(code => { for 1..5 -> $v { say $v }}, name => 'my thread');
say $t1.name; # OUTPUT: «<anon>»
say $t2.name; # OUTPUT: «my thread»
=head2 method Numeric
method Numeric(Thread:D: --> Int:D)
Returns a numeric, unique thread identifier, i.e. the same as L<id|#method_id>.
=head2 method Str
method Str(Thread:D: --> Str:D)
Returns a string which contains the invocants L<thread id|#method_id> and
L<name|#method_name>.
my $t = Thread.new(code => { for 1..5 -> $v { say $v }}, name => 'calc thread');
say $t.Str; # OUTPUT: «Thread<3>(calc thread)»
=head2 method is-initial-thread
method is-initial-thread(--> Bool)
Returns a Bool indicating whether the current thread (if called as a class
method) or the Thread object on which it is called, is the initial thread
the program started on.
say Thread.is-initial-thread; # True if this is the initial thread
say $*THREAD.is-initial-thread; # True if $*THREAD is the initial thread
Please note there is no guarantee that this is actually the main thread from
the OS's point of view. Also note that if you need this other than from a
pure introspection / debugging point of view, that there are probably better
ways to achieve what you're trying to achieve.
=head1 Routines
=head2 sub full-barrier
sub full-barrier()
Performs a full memory barrier, preventing re-ordering of reads/writes.
Required for implementing some lock-free data structures and algorithms.
=end pod
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6