Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
THREAD(3)		   Library Functions Manual		     THREAD(3)

       alt, chancreate,	chanfree, chanprint, chansetname, mainstacksize, proc-
       create, procdata, recv, recvp, recvul,  send,  sendp,  sendul,  nbrecv,
       nbrecvp,	nbrecvul, nbsend, nbsendp, nbsendul, threadcreate, threaddata,
       threadexec,  threadexecl,  threadexits,	threadexitsall,	 threadgetgrp,
       threadgetname,	threadint,  threadintgrp,  threadkill,	threadkillgrp,
       threadmain, threadnotify, threadid, threadpid, threadpin,  threadunpin,
       threadsetgrp, threadsetname, threadsetstate, threadspawn, threadspawnd,
       threadspawnl, threadwaitchan, yield - thread and	proc management

       #include	<u.h>
       #include	<libc.h>
       #include	<thread.h>

       #define CHANEND	   0
       #define CHANSND	   1
       #define CHANRCV	   2
       #define CHANNOP	   3
       #define CHANNOBLK   4

       typedef struct Alt Alt;
       struct Alt {
	   Channel *c;
	   void	   *v;
	   int	   op;
	   Channel **tag;
	   int	   entryno;
	   char	   *name;

       void	threadmain(int argc, char *argv[])
       int	mainstacksize
       int	proccreate(void	(*fn)(void*), void *arg, uint stacksize)
       int	threadcreate(void (*fn)(void*),	void *arg, uint	stacksize)
       void	threadexits(char *status)
       void	threadexitsall(char *status)
       void	yield(void)
       int	threadpin(void)
       int	threadunpin(void)

       int	threadid(void)
       int	threadgrp(void)
       int	threadsetgrp(int group)
       int	threadpid(int id)

       int	threadint(int id)
       int	threadintgrp(int group)
       int	threadkill(int id)
       int	threadkillgrp(int group)

       void	threadsetname(char *name)
       char*	threadgetname(void)

       void**	threaddata(void)
       void**	procdata(void)

       Channel*	chancreate(int elsize, int nel)
       void	chanfree(Channel *c)

       int	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	threadspawnl(int fd[3],	char *file, ...)
       int	threadspawn(int	fd[3], char *file, char	*args[])
       int	threadspawnd(int fd[3],	char *file, char *args[], char *dir)
       int	threadexecl(Channel *cpid, int fd[3], char *file, ...)
       int	threadexec(Channel *cpid, int fd[3], char *file, char *args[])
       Channel*	threadwaitchan(void)

       int	threadnotify(int (*f)(void*, char*), int in)

       The thread library provides parallel  programming  support  similar  to
       that  of	 the languages Alef and	Newsqueak.  Threads and	procs occupy a
       shared address space, communicating and synchronizing through  channels
       and shared variables.

       A  proc	is  a  Plan  9 process that contains one or more cooperatively
       scheduled threads.  Programs using threads must replace main by thread-
       main.   The thread library provides a main function that	sets up	a proc
       with a single thread executing threadmain on a stack of size mainstack-
       size (default eight kilobytes).	To set mainstacksize, declare a	global
       variable	initialized to the desired value (e.g.,	 int  mainstacksize  =

       Threadcreate  creates  a	 new  thread  in the calling proc, returning a
       unique integer identifying the thread; the thread executes fn(arg) on a
       stack of	size stacksize.	 Thread	stacks are allocated in	shared memory,
       making it valid to pass pointers	to stack variables between threads and
       procs.	Proccreate  creates a new proc,	and inside that	proc creates a
       single thread as	threadcreate would, returning the id  of  the  created
       thread.	Be aware that the calling thread may continue execution	before
       the newly created proc and thread are scheduled.	 Because of this,  arg
       should  not  point to data on the stack of a function that could	return
       before the new process is scheduled.

       Threadexits terminates the calling thread.  If the thread is  the  last
       in  its proc, threadexits also terminates the proc, using status	as the
       exit status.  Threadexitsall terminates all procs in the	program, using
       status as the exit status.

       When  the  last thread in threadmain's proc exits, the program will ap-
       pear to its parent to have exited.  The remaining procs will still  run
       together, but as	a background program.

       The  threads  in	 a proc	are coroutines,	scheduled nonpreemptively in a
       round-robin fashion.  A thread must explicitly  relinquish  control  of
       the  processor  before  another	thread in the same proc	is run.	 Calls
       that do this are	yield, proccreate, threadexec, threadexecl,  threadex-
       its,  threadspawn, threadspawnd,	threadspawnl, alt, send, and recv (and
       the calls related to send and recv--see their descriptions further on).
       Procs  are  scheduled  by  the operating	system.	 Therefore, threads in
       different procs can preempt one another in arbitrary  ways  and	should
       synchronize  their actions using	qlocks (see lock(3)) or	channel	commu-
       nication.  System calls such as read(3)	block  the  entire  proc;  all
       threads in a proc block until the system	call finishes.

       Threadpin  disables  scheduling	inside	a  proc, `pinning' the current
       thread as the only runnable one in the current proc.  Threadunpin reen-
       ables  scheduling,  allowing other procs	to run once the	current	thread
       relinquishes the	processor.  Threadpin  and  threadunpin	 can  lead  to
       deadlock.   Used	 carefully,  they  can	make library routines that use
       qlocks appear atomic relative to	the current proc, like a system	call.

       As mentioned above, each	thread has a unique integer thread id.	Thread
       ids  are	 not  reused;  they are	unique across the life of the program.
       Threadid	returns	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 of the thread that created it.   Threadgrp
       returns	the  group  id	for  the current thread; threadsetgrp sets it.
       Threadpid returns the pid of the	Plan 9 process containing  the	thread
       identified by id, or -1 if no such thread is found.

       Threadint interrupts a thread that is blocked in	a channel operation or
       system call.  Threadintgrp interrupts all threads with the given	 group
       id.   Threadkill	 marks	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.
       Threadkillgrp kills all threads with the	given  group  id.   Note  that
       threadkill and threadkillgrp will not terminate a thread	that never re-
       linquishes the processor.

       Primarily for debugging,	threads	can have string	names associated  with
       them.   Threadgetname  returns the current thread's name; threadsetname
       sets it.	 The pointer returned by threadgetname is only valid until the
       next call to threadsetname.

       Also  for  debugging, threads have a string state associated with them.
       Threadsetstate sets the state  string.	There  is  no  threadgetstate;
       since  the  thread  scheduler resets the	state to Running every time it
       runs the	thread,	it is only useful for debuggers	to inspect the state.

       Threaddata returns a pointer to a per-thread pointer that may be	 modi-
       fied  by	threaded programs for per-thread storage.  Similarly, procdata
       returns a pointer to a per-proc pointer.

       Threadexecl and threadexec are threaded analogues  of  exec  and	 execl
       (see  exec(3));	on success, they replace the calling thread and	invoke
       the external program, never returning.  (Unlike on Plan 9, the  calling
       thread  need not	be the only thread in its proc--the other threads will
       continue	executing.)  On	error, they return -1.	If cpid	is  not	 null,
       the  pid	 of the	invoked	program	will be	sent along cpid	(using sendul)
       once the	program	has been started, or -1	will be	sent if	an  error  oc-
       curs.  Threadexec and threadexecl will not access their arguments after
       sending a result	along cpid.   Thus,  programs  that  malloc  the  argv
       passed  to  threadexec  can  safely free	it once	they have received the
       cpid response.

       Threadexecl and threadexec will duplicate (see dup(3)) the  three  file
       descriptors in fd onto standard input, output, and error	for the	exter-
       nal program and then close them in the calling thread.  Beware of  code
       that sets

	      fd[0] = 0;
	      fd[1] = 1;
	      fd[2] = 2;

       to use the current standard files.  The correct code is

	      fd[0] = dup(0, -1);
	      fd[1] = dup(1, -1);
	      fd[2] = dup(2, -1);

       Threadspawnl and	threadspawn are	like threadexecl and threadexec	but do
       not replace the current thread.	They return the	 pid  of  the  invoked
       program	on  success, or	-1 on error.  Threadspawnd is like threadspawn
       but takes as its	final argument the directory in	which to run  the  in-
       voked  program.	 The  child will attempt to change into	that directory
       before running the program, but it is  only  best  effort:  failure  to
       change into the directory does not stop the running of the program.

       Threadwaitchan returns a	channel	of pointers to Waitmsg structures (see
       wait(3)).  When an exec'ed process exits, a pointer  to	a  Waitmsg  is
       sent  to	 this  channel.	  These	Waitmsg	structures have	been allocated
       with malloc(3) and should be freed after	use.

       A Channel is a buffered or unbuffered queue  for	 fixed-size  messages.
       Procs and threads send messages into the	channel	and recv messages from
       the channel.  If	the channel is unbuffered, a send operation blocks un-
       til the corresponding recv operation occurs and vice versa.  Chancreate
       allocates a new channel for messages of size elsize and with  a	buffer
       holding	nel  messages.	 If  nel  is  zero, the	channel	is unbuffered.
       Chanfree	frees a	channel	that is	 no  longer  used.   Chanfree  can  be
       called  by  either sender or receiver after the last item has been sent
       or received.  Freeing the channel will be delayed if there is a	thread
       blocked	on it until that thread	unblocks (but chanfree returns immedi-

       The name	element	in the Channel structure is a description intended for
       use in debugging.  Chansetname sets the name.

       Send sends the element pointed at by v to the channel c.	 If v is null,
       zeros are sent.	Recv receives an element from c	and stores  it	in  v.
       If  v is	null, the received value is discarded.	Send and recv return 1
       on success, -1 if interrupted.  Nbsend and nbrecv behave	similarly, but
       return 0	rather than blocking.

       Sendp,  nbsendp,	 sendul,  and  nbsendul	 send a	pointer	or an unsigned
       long; the channel must have been	initialized with the  appropriate  el-
       size.  Recvp, nbrecvp, recvul, and nbrecvul receive a pointer or	an un-
       signed long; they return	zero when a  zero  is  received,  when	inter-
       rupted,	or  (for  nbrecvp  and nbrecvul) when the operation would have
       blocked.	 To distinguish	between	these three cases, use recv or nbrecv.

       Alt can be used to recv from or send to one of a	number of channels, as
       directed	 by  an	array of Alt structures, each of which describes a po-
       tential send or receive operation.  In an Alt structure,	c is the chan-
       nel;  v	the  value  pointer (which may be null); and op	the operation:
       CHANSND for a send operation, CHANRECV for a  recv  operation;  CHANNOP
       for no operation	(useful	when alt is called with	a varying set of oper-
       ations).	 The array of Alt structures is	terminated by an entry with op
       CHANEND	or  CHANNOBLK.	If at least one	Alt structure can proceed, one
       of them is chosen at random to be executed.  Alt	returns	the  index  of
       the  chosen  structure.	 If  no	operations can proceed and the list is
       terminated with CHANNOBLK, alt returns the  index  of  the  terminating
       CHANNOBLK structure.  Otherwise,	alt blocks until one of	the operations
       can proceed, eventually returning the index of the structure  executes.
       Alt returns -1 when interrupted.	 The tag and entryno fields in the Alt
       structure are used internally by	alt and	need not be initialized.  They
       are not used between alt	calls.

       Chanprint formats its arguments in the manner of	print(3) and sends the
       result to the channel c.	 The string delivered by  chanprint  is	 allo-
       cated with malloc(3) and	should be freed	upon receipt.

       Thread library functions	do not return on failure; if errors occur, the
       entire program is aborted.

       Threaded	programs should	use threadnotify in place of atnotify (see no-

       It  is  safe  to	 use  sysfatal(3) in threaded programs.	 Sysfatal will
       print the error string and call threadexitsall.

       It is not safe to call rfork in a  threaded  program,  except  to  call
       rfork(RFNOTEG) from the main proc before	any other procs	have been cre-
       ated.  To create	new processes, use proccreate.

       /usr/local/plan9/acid/thread contains useful acid(1) functions for  de-
       bugging threaded	programs.

       /usr/local/plan9/src/libthread/test contains some example programs.


       intro(3), ioproc(3)

       To  avoid  name	conflicts, alt,	nbrecv,	nbrecvp, nbrecvul, nbsend, nb-
       sendp, nbsendul,	recv, recvp, recvul, send, sendp, and sendul  are  de-
       fined  as  macros that expand to	chanalt, channbrecv, and so on.	 Yield
       is defined as a macro that expands to threadyield.  See intro(3).

       Threadint, threadintgrp,	threadkill, threadkillgrp  and	threadpid  are

       The implementation of threadnotify may not be correct.

       There  appears  to  be  a  race	in  the	 Linux	NPTL implementation of
       pthread_exit .  Call threadexitsall rather than coordinating a simulta-
       neous threadexits among many threads.



Want to link to this manual page? Use this URL:

home | help