Blob


1 .TH THREAD 3
2 .SH NAME
3 alt,
4 chancreate,
5 chanfree,
6 chaninit,
7 chanprint,
8 mainstacksize,
9 proccreate,
10 procdata,
11 procexec,
12 procexecl,
13 procrfork,
14 recv,
15 recvp,
16 recvul,
17 send,
18 sendp,
19 sendul,
20 nbrecv,
21 nbrecvp,
22 nbrecvul,
23 nbsend,
24 nbsendp,
25 nbsendul,
26 threadcreate,
27 threaddata,
28 threadexits,
29 threadexitsall,
30 threadgetgrp,
31 threadgetname,
32 threadint,
33 threadintgrp,
34 threadkill,
35 threadkillgrp,
36 threadmain,
37 threadnotify,
38 threadid,
39 threadpid,
40 threadsetgrp,
41 threadsetname,
42 threadwaitchan,
43 yield \- thread and proc management
44 .SH SYNOPSIS
45 .PP
46 .de EX
47 .nf
48 .ft B
49 ..
50 .de EE
51 .fi
52 .ft R
53 ..
54 .EX
55 .ta 4n +4n +4n +4n +4n +4n +4n
56 #include <u.h>
57 #include <libc.h>
58 #include <thread.h>
59 .sp
60 #define CHANEND 0
61 #define CHANSND 1
62 #define CHANRCV 2
63 #define CHANNOP 3
64 #define CHANNOBLK 4
65 .sp
66 .ta \w' 'u +\w'Channel 'u
67 typedef struct Alt Alt;
68 struct Alt {
69 Channel *c;
70 void *v;
71 int op;
72 Channel **tag;
73 int entryno;
74 };
75 .fi
76 .de XX
77 .if t .sp 0.5
78 .if n .sp
79 ..
80 .PP
81 .nf
82 .ft L
83 .ta \w'\fLChannel* 'u +4n +4n +4n +4n
84 void threadmain(int argc, char *argv[])
85 int mainstacksize
86 int proccreate(void (*fn)(void*), void *arg, uint stacksize)
87 int procrfork(void (*fn)(void*), void *arg, uint stacksize,
88 int rforkflag)
89 int threadcreate(void (*fn)(void*), void *arg, uint stacksize)
90 void threadexits(char *status)
91 void threadexitsall(char *status)
92 void yield(void)
93 .XX
94 int threadid(void)
95 int threadgrp(void)
96 int threadsetgrp(int group)
97 int threadpid(int id)
98 .XX
99 int threadint(int id)
100 int threadintgrp(int group)
101 int threadkill(int id)
102 int threadkillgrp(int group)
103 .XX
104 void threadsetname(char *name)
105 char* threadgetname(void)
106 .XX
107 void** threaddata(void)
108 void** procdata(void)
109 .XX
110 int chaninit(Channel *c, int elsize, int nel)
111 Channel* chancreate(int elsize, int nel)
112 void chanfree(Channel *c)
113 .XX
114 int alt(Alt *alts)
115 int recv(Channel *c, void *v)
116 void* recvp(Channel *c)
117 ulong recvul(Channel *c)
118 int nbrecv(Channel *c, void *v)
119 void* nbrecvp(Channel *c)
120 ulong nbrecvul(Channel *c)
121 int send(Channel *c, void *v)
122 int sendp(Channel *c, void *v)
123 int sendul(Channel *c, ulong v)
124 int nbsend(Channel *c, void *v)
125 int nbsendp(Channel *c, void *v)
126 int nbsendul(Channel *c, ulong v)
127 int chanprint(Channel *c, char *fmt, ...)
128 .XX
129 int procexecl(Channel *cpid, char *file, ...)
130 int procexec(Channel *cpid, char *file, char *args[])
131 Channel* threadwaitchan(void)
132 .XX
133 int threadnotify(int (*f)(void*, char*), int in)
134 .EE
135 .SH DESCRIPTION
136 .PP
137 The thread library provides parallel programming support similar to that
138 of the languages
139 Alef and Newsqueak.
140 Threads
141 and
142 procs
143 occupy a shared address space,
144 communicating and synchronizing through
145 .I channels
146 and shared variables.
147 .PP
149 .I proc
150 is a Plan 9 process that contains one or more cooperatively scheduled
151 .IR threads .
152 Programs using threads must replace
153 .I main
154 by
155 .IR threadmain .
156 The thread library provides a
157 .I main
158 function that sets up a proc with a single thread executing
159 .I threadmain
160 on a stack of size
161 .I mainstacksize
162 (default eight kilobytes).
163 To set
164 .IR mainstacksize ,
165 declare a global variable
166 initialized to the desired value
167 .RI ( e.g. ,
168 .B int
169 .B mainstacksize
170 .B =
171 .BR 1024 ).
172 .PP
173 .I Threadcreate
174 creates a new thread in the calling proc, returning a unique integer
175 identifying the thread; the thread
176 executes
177 .I fn(arg)
178 on a stack of size
179 .IR stacksize .
180 Thread stacks are allocated in shared memory, making it valid to pass
181 pointers to stack variables between threads and procs.
182 .I Procrfork
183 creates a new proc, and inside that proc creates
184 a single thread as
185 .I threadcreate
186 would,
187 returning the id of the created thread.
188 .I Procrfork
189 creates the new proc by calling
190 .B rfork
191 (see
192 .IR fork (3))
193 with flags
194 .BR RFPROC|RFMEM|RFNOWAIT| \fIrforkflag\fR.
195 (The thread library depends on all its procs
196 running in the same rendezvous group.
197 Do not include
198 .B RFREND
199 in
200 .IR rforkflag .)
201 .I Proccreate
202 is identical to
203 .I procrfork
204 with
205 .I rforkflag
206 set to zero.
207 Be aware that the calling thread may continue
208 execution before
209 the newly created proc and thread
210 are scheduled.
211 Because of this,
212 .I arg
213 should not point to data on the stack of a function that could
214 return before the new process is scheduled.
215 .PP
216 .I Threadexits
217 terminates the calling thread.
218 If the thread is the last in its proc,
219 .I threadexits
220 also terminates the proc, using
221 .I status
222 as the exit status.
223 .I Threadexitsall
224 terminates all procs in the program,
225 using
226 .I status
227 as the exit status.
228 .PP
229 The threads in a proc are coroutines, scheduled nonpreemptively
230 in a round-robin fashion.
231 A thread must explicitly relinquish control of the processor
232 before another thread in the same proc is run.
233 Calls that do this are
234 .IR yield ,
235 .IR proccreate ,
236 .IR procexec ,
237 .IR procexecl ,
238 .IR threadexits ,
239 .IR alt ,
240 .IR send ,
241 and
242 .I recv
243 (and the calls related to
244 .I send
245 and
246 .IR recv \(emsee
247 their descriptions further on).
248 Procs are scheduled by the operating system.
249 Therefore, threads in different procs can preempt one another
250 in arbitrary ways and should synchronize their
251 actions using
252 .B qlocks
253 (see
254 .IR lock (3))
255 or channel communication.
256 System calls such as
257 .IR read (3)
258 block the entire proc;
259 all threads in a proc block until the system call finishes.
260 .PP
261 As mentioned above, each thread has a unique integer thread id.
262 Thread ids are not reused; they are unique across the life of the program.
263 .I Threadid
264 returns the id for the current thread.
265 Each thread also has a thread group id.
266 The initial thread has a group id of zero.
267 Each new thread inherits the group id of
268 the thread that created it.
269 .I Threadgrp
270 returns the group id for the current thread;
271 .I threadsetgrp
272 sets it.
273 .I Threadpid
274 returns the pid of the Plan 9 process containing
275 the thread identified by
276 .IR id ,
277 or \-1
278 if no such thread is found.
279 .PP
280 .I Threadint
281 interrupts a thread that is blocked in a channel operation
282 or system call.
283 .I Threadintgrp
284 interrupts all threads with the given group id.
285 .I Threadkill
286 marks a thread to die when it next relinquishes the processor
287 (via one of the calls listed above).
288 If the thread is blocked in a channel operation or system call,
289 it is also interrupted.
290 .I Threadkillgrp
291 kills all threads with the given group id.
292 Note that
293 .I threadkill
294 and
295 .I threadkillgrp
296 will not terminate a thread that never relinquishes
297 the processor.
298 .PP
299 Primarily for debugging,
300 threads can have string names associated with them.
301 .I Threadgetname
302 returns the current thread's name;
303 .I threadsetname
304 sets it.
305 The pointer returned by
306 .I threadgetname
307 is only valid until the next call to
308 .IR threadsetname .
309 .PP
310 .I Threaddata
311 returns a pointer to a per-thread pointer
312 that may be modified by threaded programs for
313 per-thread storage.
314 Similarly,
315 .I procdata
316 returns a pointer to a per-proc pointer.
317 .PP
318 .I Procexecl
319 and
320 .I procexec
321 are threaded analogues of
322 .I exec
323 and
324 .I execl
325 (see
326 .IR exec (3));
327 on success,
328 they replace the calling thread (which must be the only thread in its proc)
329 and invoke the external program, never returning.
330 On error, they return \-1.
331 If
332 .I cpid
333 is not null, the pid of the invoked program
334 will be sent along
335 .I cpid
336 once the program has been started, or \-1 will be sent if an
337 error occurs.
338 .I Procexec
339 and
340 .I procexecl
341 will not access their arguments after sending a result
342 along
343 .IR cpid .
344 Thus, programs that malloc the
345 .I argv
346 passed to
347 .I procexec
348 can safely free it once they have
349 received the
350 .I cpid
351 response.
352 .I Threadwaitchan
353 returns a channel of pointers to
354 .B Waitmsg
355 structures (see
356 .IR wait (3)).
357 When an exec'ed process exits, a pointer to a
358 .B Waitmsg
359 is sent to this channel.
360 These
361 .B Waitmsg
362 structures have been allocated with
363 .IR malloc (3)
364 and should be freed after use.
365 .PP
367 .B Channel
368 is a buffered or unbuffered queue for fixed-size messages.
369 Procs and threads
370 .I send
371 messages into the channel and
372 .I recv
373 messages from the channel. If the channel is unbuffered, a
374 .I send
375 operation blocks until the corresponding
376 .I recv
377 operation occurs and
378 .IR "vice versa" .
379 .I Chaninit
380 initializes a
381 .B Channel
382 for messages of size
383 .I elsize
384 and with a buffer holding
385 .I nel
386 messages.
387 If
388 .I nel
389 is zero, the channel is unbuffered.
390 .IR Chancreate
391 allocates a new channel and initializes it.
392 .I Chanfree
393 frees a channel that is no longer used.
394 .I Chanfree
395 can be called by either sender or receiver after the last item has been
396 sent or received. Freeing the channel will be delayed if there is a thread
397 blocked on it until that thread unblocks (but
398 .I chanfree
399 returns immediately).
400 .PP
401 .I Send
402 sends the element pointed at by
403 .I v
404 to the channel
405 .IR c .
406 If
407 .I v
408 is null, zeros are sent.
409 .I Recv
410 receives an element from
411 .I c
412 and stores it in
413 .IR v .
414 If
415 .I v
416 is null,
417 the received value is discarded.
418 .I Send
419 and
420 .I recv
421 return 1 on success, \-1 if interrupted.
422 .I Nbsend
423 and
424 .I nbrecv
425 behave similarly, but return 0 rather than blocking.
426 .PP
427 .IR Sendp ,
428 .IR nbsendp ,
429 .IR sendul ,
430 and
431 .I nbsendul
432 send a pointer or an unsigned long; the channel must
433 have been initialized with the appropriate
434 .IR elsize .
435 .IR Recvp ,
436 .IR nbrecvp ,
437 .IR recvul ,
438 and
439 .I nbrecvul
440 receive a pointer or an unsigned long;
441 they return zero when a zero is received,
442 when interrupted, or
443 (for
444 .I nbrecvp
445 and
446 .IR nbrecvul )
447 when the operation would have blocked.
448 To distinguish between these three cases,
449 use
450 .I recv
451 or
452 .IR nbrecv .
453 .PP
454 .I Alt
455 can be used to recv from or send to one of a number of channels,
456 as directed by an array of
457 .B Alt
458 structures,
459 each of which describes a potential send or receive operation.
460 In an
461 .B Alt
462 structure,
463 .B c
464 is the channel;
465 .B v
466 the value pointer (which may be null); and
467 .B op
468 the operation:
469 .B CHANSND
470 for a send operation,
471 .B CHANRECV
472 for a recv operation;
473 .B CHANNOP
474 for no operation
475 (useful
476 when
477 .I alt
478 is called with a varying set of operations).
479 The array of
480 .B Alt
481 structures is terminated by an entry with
482 .I op
483 .B CHANEND
484 or
485 .BR CHANNOBLK .
486 If at least one
487 .B Alt
488 structure can proceed, one of them is
489 chosen at random to be executed.
490 .I Alt
491 returns the index of the chosen structure.
492 If no operations can proceed and the list is terminated with
493 .BR CHANNOBLK ,
494 .I alt
495 returns the index of the terminating
496 .B CHANNOBLK
497 structure.
498 Otherwise,
499 .I alt
500 blocks until one of the operations can proceed,
501 eventually returning the index of the structure executes.
502 .I Alt
503 returns \-1 when interrupted.
504 The
505 .B tag
506 and
507 .B entryno
508 fields in the
509 .B Alt
510 structure are used internally by
511 .I alt
512 and need not be initialized.
513 They are not used between
514 .I alt
515 calls.
516 .PP
517 .I Chanprint
518 formats its arguments in the manner of
519 .IR print (3)
520 and sends the result to the channel
521 .IR c.
522 The string delivered by
523 .I chanprint
524 is allocated with
525 .IR malloc (3)
526 and should be freed upon receipt.
527 .PP
528 Thread library functions do not return on failure;
529 if errors occur, the entire program is aborted.
530 .PP
531 Threaded programs should use
532 .I threadnotify
533 in place of
534 .I atnotify
535 (see
536 .IR notify (3)).
537 .PP
538 It is safe to use
539 .B sysfatal
540 (see
541 .IR perror (3))
542 in threaded programs.
543 .I Sysfatal
544 will print the error string and call
545 .IR threadexitsall .
546 .PP
547 It is safe to use
548 .IR rfork
549 (see
550 .IR fork (3))
551 to manage the namespace, file descriptors, note group, and environment of a
552 single process.
553 That is, it is safe to call
554 .I rfork
555 with the flags
556 .BR RFNAMEG ,
557 .BR RFFDG ,
558 .BR RFCFDG ,
559 .BR RFNOTEG ,
560 .BR RFENVG ,
561 and
562 .BR RFCENVG.
563 (To create new processes, use
564 .I proccreate
565 and
566 .IR procrfork .)
567 As mentioned above,
568 the thread library depends on all procs being in the
569 same rendezvous group; do not change the rendezvous
570 group with
571 .IR rfork .
572 .SH FILES
573 .B /usr/local/plan9/acid/thread
574 contains useful
575 .IR acid (1)
576 functions for debugging threaded programs.
577 .PP
578 .B /usr/local/plan9/src/libthread/example.c
579 contains a full example program.
580 .SH SOURCE
581 .B /usr/local/plan9/src/libthread
582 .SH SEE ALSO
583 .IR intro (3),
584 .IR ioproc (3)