669 lines · 13.2 KB · Text
RawDownload
.TH THREAD 2.SH NAMEalt,chanclose,chanclosing,chancreate,chanfree,chaninit,chanprint,mainstacksize,nbrecv,nbrecvp,nbrecvul,nbsend,nbsendp,nbsendul,needstack,proccreate,procdata,procexec,procexecl,procrfork,recv,recvp,recvul,send,sendp,sendul,threadcreate,threaddata,threadexits,threadexitsall,threadgetgrp,threadgetname,threadid,threadint,threadintgrp,threadkill,threadkillgrp,threadmain,threadnotify,threadpid,threadsetgrp,threadsetname,threadwaitchan,tprivaddr,tprivalloc,tprivfree,yield \- thread and proc management.SH SYNOPSIS.EX.ta 4n +4n +4n +4n +4n +4n +4n#include <u.h>#include <libc.h>#include <thread.h>.sptypedef enum {	CHANEND,	CHANSND,	CHANRCV,	CHANNOP,	CHANNOBLK,} ChanOp;.sp.ta \w'    'u +\w'Channel 'utypedef struct Alt Alt;struct Alt {	Channel	*c;   /* channel */	void	*v;   /* pointer to value */	ChanOp	op;   /* operation */	char	*err; /* did the op fail? */	/*	 * the next variables are used internally to alt	 * they need not be initialized	 */	Channel	**tag;   /* pointer to rendez-vous tag */	int	entryno; /* entry number */};.fi.de XX.ift .sp 0.5.ifn .sp...PP.nf.ft L.ta \w'\fLChannel* 'u +4n +4n +4n +4nvoid	threadmain(int argc, char *argv[])int	mainstacksizeint	proccreate(void (*fn)(void*), void *arg, uint stacksize)int	procrfork(void (*fn)(void*), void *arg, uint stacksize,		int rforkflag)int	threadcreate(void (*fn)(void*), void *arg, uint stacksize)void	threadexits(char *status)void	threadexitsall(char *status)void	yield(void).XXint	threadid(void)int	threadgrp(void)int	threadsetgrp(int group)int	threadpid(int id).XXint	threadint(int id)void	threadintgrp(int group)void	threadkill(int id)int	threadkillgrp(int group).XXvoid	threadsetname(char *name, ...)char*	threadgetname(void).XXvoid**	threaddata(void)void**	procdata(void).XXint	chaninit(Channel *c, int elsize, int nel)Channel*	chancreate(int elsize, int nel)void	chanfree(Channel *c).XXint	alt(Alt *alts)int	recv(Channel *c, void *v)void*	recvp(Channel *c)ulong	recvul(Channel *c)int	nbrecv(Channel *c, void *v)void*	nbrecvp(Channel *c)ulong	nbrecvul(Channel *c)int	send(Channel *c, void *v)int	sendp(Channel *c, void *v)int	sendul(Channel *c, ulong v)int	nbsend(Channel *c, void *v)int	nbsendp(Channel *c, void *v)int	nbsendul(Channel *c, ulong v)int	chanprint(Channel *c, char *fmt, ...)int	chanclose(Channel *c);int	chanclosing(Channel *c);.XXvoid	procexecl(Channel *cpid, char *file, ...)void	procexec(Channel *cpid, char *file, char *args[])Channel*	threadwaitchan(void).XXint	tprivalloc(void)void	tprivfree(int i)void**	tprivaddr(int i).XXvoid	needstack(int nbytes).XXint	threadnotify(int (*f)(void*, char*), int in).EE.SH DESCRIPTIONThe thread library provides parallel programming support similar to thatof the languagesAlef and Newsqueak..I Threadsand.I procsoccupy a shared address space,communicating and synchronizing through.I channelsand shared variables..PPA.I procis a Plan 9 process that contains one or more cooperatively-scheduled.IR threads .Programs using threads must replace.I mainby.IR threadmain .The thread library provides a.I mainfunction that sets up a proc with a single thread executing.I threadmainon a stack of size.I mainstacksize(default eight kilobytes).To set.IR mainstacksize ,declare a global variableinitialized to the desired value.RI ( e.g. ,.B int.B mainstacksize.B =.BR 1024 )..SS Creation.I Threadcreatecreates a new thread in the calling proc, returning a unique integeridentifying the thread; the threadexecutes.I fn(arg)on a stack of size.IR stacksize .Thread stacks are allocated in shared memory, making it valid to passpointers to stack variables between threads and procs.Since there is no stack segment protection, the function.I needstackmay be used to.I abortif the caller has not left at least.I nbytesof stack available..I Procrforkcreates a new proc, and inside that proc createsa single thread as.I threadcreatewould,returning the id of the created thread..I Procrforkcreates the new proc by calling.B rfork(see.IR fork (2))with flags.BR RFPROC|RFMEM|RFNOWAIT| \fIrforkflag\fR.(The thread library depends on all its procsrunning in the same rendezvous group.Do not include.B RFRENDin.IR rforkflag .).I Proccreateis identical to.I procrforkwith.I rforkflagset to zero.Be aware that the calling thread may continueexecution beforethe newly created proc and threadare scheduled.Because of this,.I argshould not point to data on the stack of a function that couldreturn before the new process is scheduled..PP.I Threadexitsterminates the calling thread.If the thread is the last in its proc,.I threadexitsalso terminates the proc, using.I statusas the exit status..I Threadexitsallterminates all procs in the program,using.I statusas the exit status..SS SchedulingThe threads in a proc are coroutines, scheduled non-preemptivelyin a round-robin fashion.A thread must explicitly relinquish control of the processorbefore another thread in the same proc is run.Calls that do this are.IR yield ,.IR proccreate ,.IR procexec ,.IR procexecl ,.IR threadexits ,.IR alt ,.IR send ,and.I recv(and the calls related to.I sendand.IR recv \(emseetheir descriptions further on),plus these from.IR lock (2):.IR qlock ,.IR rlock ,.IR wlock ,.IR rsleep .Procs are scheduled by the operating system.Therefore, threads in different procs can preempt one anotherin arbitrary ways and should synchronize theiractions using.B qlocks(see.IR lock (2))or channel communication.System calls such as.IR read (2)block the entire proc;all threads in a proc block until the system call finishes..PPAs mentioned above, each thread has a unique integer thread id.Thread ids are not reused; they are unique across the life of the program..I Threadidreturns the id for the current thread.Each thread also has a thread group id.The initial thread has a group id of zero.Each new thread inherits the group id ofthe thread that created it..I Threadgrpreturns the group id for the current thread;.I threadsetgrpsets it..I Threadpidreturns the pid of the Plan 9 process containingthe thread identified by.IR id ,or \-1if no such thread is found..PP.I Threadintinterrupts a thread that is blocked in a channel operationor system call..I Threadintgrpinterrupts all threads with the given group id..I Threadkillmarks a thread to die when it next relinquishes the processor(via one of the calls listed above).If the thread is blocked in a channel operation or system call,it is also interrupted..I Threadkillgrpkills all threads with the given group id.Note that.I threadkilland.I threadkillgrpwill not terminate a thread that never relinquishesthe processor..SS Names and per-thread dataPrimarily for debugging,threads can have string names associated with them..I Threadgetnamereturns the current thread's name;.I threadsetnamesets it.The pointer returned by.I threadgetnameis only valid until the next call to.IR threadsetname ..PP.I Threaddatareturns a pointer to a per-thread pointerthat may be modified by threaded programs forper-thread storage.Similarly,.I procdatareturns a pointer to a per-proc pointer..SS Executing new programs.I Procexecland.I procexecare threaded analogues of.I execand.I execl(see.IR exec (2));on success,they replace the calling thread (which must be the only thread in its proc)and invoke the external program, never returning.On error, they return \-1.If.I cpidis not null, the pid of the invoked programwill be sent along.I cpidonce the program has been started, or \-1 will be sent if anerror occurs..I Procexecand.I procexeclwill not access their arguments after sending a resultalong.IR cpid .Thus, programs that malloc the.I argvpassed to.I procexeccan safely free it once they havereceived the.I cpidresponse.Note that the mount point.B /mnt/tempmust exist;.I procexec(l)mount pipes there..PP.I Threadwaitchanreturns a channel of pointers to.B Waitmsgstructures (see.IR wait (2)).When an exec'ed process exits, a pointer to a.B Waitmsgis sent to this channel.These.B Waitmsgstructures have been allocated with.IR malloc (2)and should be freed after use..SS ChannelsA.B Channelis a buffered or unbuffered queue for fixed-size messages.Procs and threads.I sendmessages into the channel and.I recvmessages from the channel.  If the channel is unbuffered, a.I sendoperation blocks until the corresponding.I recvoperation occurs and.IR "vice versa" ..I Chaninitinitializes a.B Channelfor messages of size.I elsizeand with a buffer holding.I nelmessages.If.I nelis zero, the channel is unbuffered..IR Chancreateallocates a new channel and initializes it..I Chanfreefrees a channel that is no longer used..I Chanfreecan be called by either sender or receiver after the last item has beensent or received.  Freeing the channel will be delayed if there is a threadblocked on it until that thread unblocks (but.I chanfreereturns immediately)..PP.I Sendsends the element pointed at by.I vto the channel.IR c .If.I vis null, zeros are sent..I Recvreceives an element from.I cand stores it in.IR v .If.I vis null,the received value is discarded..I Sendand.I recvreturn 1 on success, \-1 if interrupted..I Nbsendand.I nbrecvbehave similarly, but return 0 rather than blocking..PP.IR Sendp ,.IR nbsendp ,.IR sendul ,and.I nbsendulsend a pointer or an unsigned long; the channel musthave been initialized with the appropriate.IR elsize ..IR Recvp ,.IR nbrecvp ,.IR recvul ,and.I nbrecvulreceive a pointer or an unsigned long;they return zero when a zero is received,when interrupted, or(for.I nbrecvpand.IR nbrecvul )when the operation would have blocked.To distinguish between these three cases,use.I recvor.IR nbrecv ..PP.I Altcan be used to recv from or send to one of a number of channels,as directed by an array of.B Altstructures,each of which describes a potential send or receive operation.In an.B Altstructure,.B cis the channel;.B vthe value pointer (which may be null); and.B opthe operation:.B CHANSNDfor a send operation,

Lines 1–500 of 669.