📄 pth.pod
字号:
just raises a signal via raise(3) or kill(2), its delivered to an arbitrarythread which has this signal not blocked. With pth_raise(3) one can send asignal to a thread and its guarantees that only this thread gets the signaldelivered. But keep in mind that nevertheless the signals I<action> is stillconfigured I<process>-wide. When I<sig> is 0 plain thread checking isperformed, i.e., `C<pth_raise(tid, 0)>' returns C<TRUE> when thread I<tid>still exists in the B<PTH> system but doesn't send any signal to it.=item int B<pth_yield>(pth_t I<tid>);This explicitly yields back the execution control to the scheduler thread.Usually the execution is implicitly transferred back to the scheduler when athread waits for an event. But when a thread has to do larger CPU bursts, itcan be reasonable to interrupt it explicitly by doing a few pth_yield(3) callsto give other threads a chance to execute, too. This obviously is thecooperating part of B<Pth>. A thread I<has not> to yield execution, ofcourse. But when you want to program a server application with good responsetimes the threads should be cooperative, i.e., when they should split their CPUbursts into smaller units with this call.Usually one specifies I<tid> as C<NULL> to indicate to the scheduler that itcan freely decide which thread to dispatch next. But if one wants to indicateto the scheduler that a particular thread should be favored on the nextdispatching step, one can specify this thread explicitly. This allows theusage of the old concept of I<coroutines> where a thread/routine switches to aparticular cooperating thread. If I<tid> is not C<NULL> and points to a I<new>or I<ready> thread, it is guaranteed that this thread receives executioncontrol on the next dispatching step. If I<tid> is in a different state (thatis, not in C<PTH_STATE_NEW> or C<PTH_STATE_READY>) an error is reported.The function usually returns C<TRUE> for success and only C<FALSE> (withC<errno> set to C<EINVAL>) if I<tid> specified an invalid or still notnew or ready thread.=item int B<pth_nap>(pth_time_t I<naptime>);This functions suspends the execution of the current thread until I<naptime>is elapsed. I<naptime> is of type C<pth_time_t> and this way has theoreticallya resolution of one microsecond. In practice you should neither rely on thisnor that the thread is awakened exactly after I<naptime> has elapsed. It'sonly guarantees that the thread will sleep at least I<naptime>. But becauseof the non-preemptive nature of B<Pth> it can last longer (when another threadkept the CPU for a long time). Additionally the resolution is dependent of theimplementation of timers by the operating system and these usually have only aresolution of 10 microseconds or larger. But usually this isn't important foran application unless it tries to use this facility for real time tasks.=item int B<pth_wait>(pth_event_t I<ev>);This is the link between the scheduler and the event facility (see below forthe various pth_event_xxx() functions). It's modeled like select(2), i.e., onegives this function one or more events (in the event ring specified by I<ev>)on which the current thread wants to wait. The scheduler awakes thethread when one ore more of them occurred or failed after taggingthem as such. The I<ev> argument is a I<pointer> to an event ringwhich isn't changed except for the tagging. pth_wait(3) returns thenumber of occurred or failed events and the application can usepth_event_status(3) to test which events occurred or failed.=item int B<pth_cancel>(pth_t I<tid>);This cancels a thread I<tid>. How the cancellation is done depends on thecancellation state of I<tid> which the thread can configure itself. When itsstate is C<PTH_CANCEL_DISABLE> a cancellation request is just made pending.When it is C<PTH_CANCEL_ENABLE> it depends on the cancellation type what isperformed. When its C<PTH_CANCEL_DEFERRED> again the cancellation request isjust made pending. But when its C<PTH_CANCEL_ASYNCHRONOUS> the thread isimmediately canceled before pth_cancel(3) returns. The effect of a threadcancellation is equal to implicitly forcing the thread to call`C<pth_exit(PTH_CANCELED)>' at one of his cancellation points. In B<Pth>thread enter a cancellation point either explicitly via pth_cancel_point(3) orimplicitly by waiting for an event.=item int B<pth_abort>(pth_t I<tid>);This is the cruel way to cancel a thread I<tid>. When it's already dead andwaits to be joined it just joins it (via `C<pth_join(>I<tid>C<, NULL)>') andthis way kicks it out of the system. Else it forces the thread to be notjoinable and to allow asynchronous cancellation and then cancels it via`C<pth_cancel(>I<tid>C<)>'.=item int B<pth_join>(pth_t I<tid>, void **I<value>);This joins the current thread with the thread specified via I<tid>.It first suspends the current thread until the I<tid> thread hasterminated. Then it is awakened and stores the value of I<tid>'spth_exit(3) call into *I<value> (if I<value> and not C<NULL>) andreturns to the caller. A thread can be joined only when it has theattribute C<PTH_ATTR_JOINABLE> set to C<TRUE> (the default). A threadcan only be joined once, i.e., after the pth_join(3) call the threadI<tid> is completely removed from the system.=item void B<pth_exit>(void *I<value>);This terminates the current thread. Whether it's immediately removedfrom the system or inserted into the dead queue of the scheduler dependson its join type which was specified at spawning time. If it has theattribute C<PTH_ATTR_JOINABLE> set to C<FALSE>, it's immediately removedand I<value> is ignored. Else the thread is inserted into the dead queueand I<value> remembered for a subsequent pth_join(3) call by anotherthread.=back=head2 UtilitiesUtility functions.=over 4=item int B<pth_fdmode>(int I<fd>, int I<mode>);This switches the non-blocking mode flag on file descriptor I<fd>. Theargument I<mode> can be C<PTH_FDMODE_BLOCK> for switching I<fd> into blockingI/O mode, C<PTH_FDMODE_NONBLOCK> for switching I<fd> into non-blocking I/Omode or C<PTH_FDMODE_POLL> for just polling the current mode. The current modeis returned (either C<PTH_FDMODE_BLOCK> or C<PTH_FDMODE_NONBLOCK>) orC<PTH_FDMODE_ERROR> on error. Keep in mind that since B<Pth> 1.1 there is nolonger a requirement to manually switch a file descriptor into non-blockingmode in order to use it. This is automatically done temporarily inside B<Pth>.Instead when you now switch a file descriptor explicitly into non-blockingmode, pth_read(3) or pth_write(3) will never block the current thread.=item pth_time_t B<pth_time>(long I<sec>, long I<usec>);This is a constructor for a C<pth_time_t> structure which is a convenientfunction to avoid temporary structure values. It returns a I<pth_time_t>structure which holds the absolute time value specified by I<sec> and I<usec>.=item pth_time_t B<pth_timeout>(long I<sec>, long I<usec>);This is a constructor for a C<pth_time_t> structure which is a convenientfunction to avoid temporary structure values. It returns a I<pth_time_t>structure which holds the absolute time value calculated by adding I<sec> andI<usec> to the current time.=item Sfdisc_t *B<pth_sfiodisc>(void);This functions is always available, but only reasonably usable when B<Pth>was built with B<Sfio> support (C<--with-sfio> option) and C<PTH_EXT_SFIO> isthen defined by C<pth.h>. It is useful for applications which want to use thecomprehensive B<Sfio> I/O library with the B<Pth> threading library. Then thisfunction can be used to get an B<Sfio> discipline structure (C<Sfdisc_t>)which can be pushed onto B<Sfio> streams (C<Sfio_t>) in order to let thisstream use pth_read(3)/pth_write(2) instead of read(2)/write(2). The benefitis that this way I/O on the B<Sfio> stream does only block the current threadinstead of the whole process. The application has to free(3) the C<Sfdisc_t>structure when it is no longer needed. The Sfio package can be found athttp://www.research.att.com/sw/tools/sfio/.=back=head2 Cancellation ManagementB<Pth> supports POSIX style thread cancellation via pth_cancel(3) and thefollowing two related functions:=over 4=item void B<pth_cancel_state>(int I<newstate>, int *I<oldstate>);This manages the cancellation state of the current thread. When I<oldstate>is not C<NULL> the function stores the old cancellation state under thevariable pointed to by I<oldstate>. When I<newstate> is not C<0> it sets thenew cancellation state. I<oldstate> is created before I<newstate> is set. Astate is a combination of C<PTH_CANCEL_ENABLE> or C<PTH_CANCEL_DISABLE> andC<PTH_CANCEL_DEFERRED> or C<PTH_CANCEL_ASYNCHRONOUS>.C<PTH_CANCEL_ENABLE|PTH_CANCEL_DEFERRED> (or C<PTH_CANCEL_DEFAULT>) is thedefault state where cancellation is possible but only at cancellation points.Use C<PTH_CANCEL_DISABLE> to complete disable cancellation for a thread andC<PTH_CANCEL_ASYNCHRONOUS> for allowing asynchronous cancellations, i.e.,cancellations which can happen at any time.=item void B<pth_cancel_point>(void);This explicitly enter a cancellation point. When the current cancellationstate is C<PTH_CANCEL_DISABLE> or no cancellation request is pending, this hasno side-effect and returns immediately. Else it calls`C<pth_exit(PTH_CANCELED)>'.=back=head2 Event HandlingB<Pth> has a very flexible event facility which is linked into the schedulerthrough the pth_wait(3) function. The following functions provide the handlingof event rings.=over 4=item pth_event_t B<pth_event>(unsigned long I<spec>, ...);This creates a new event ring consisting of a single initial event. The typeof the generated event is specified by I<spec>. The following types areavailable:=over 4=item C<PTH_EVENT_FD>This is a file descriptor event. One or more of C<PTH_UNTIL_FD_READABLE>,C<PTH_UNTIL_FD_WRITEABLE> or C<PTH_UNTIL_FD_EXCEPTION> have to be OR-ed intoI<spec> to specify on which state of the file descriptor you want to wait. Thefile descriptor itself has to be given as an additional argument. Example:`C<pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE, fd)>'.=item C<PTH_EVENT_SELECT>This is a multiple file descriptor event modeled directly after the select(2)call (actually it is also used to implement pth_select(3) internally). It's aconvenient way to wait for a large set of file descriptors at once and at eachfile descriptor for a different type of state. Additionally as a niceside-effect one receives the number of file descriptors which causes the eventto be occurred (using BSD semantics, i.e., when a file descriptor occurred intwo sets it's counted twice). The arguments correspond directly to theselect(2) function arguments except that there is no timeout argument (becausetimeouts already can be handled via C<PTH_EVENT_TIME> events).Example: `C<pth_event(PTH_EVENT_SELECT, &rc, nfd, rfds, wfds, efds)>' whereC<rc> has to be of type `C<int *>', C<nfd> has to be of type `C<int>' andC<rfds>, C<wfds> and C<efds> have to be of type `C<fd_set *>' (seeselect(2)). The number of occurred file descriptors are stored in C<rc>.=item C<PTH_EVENT_SIGS>This is a signal set event. The two additional arguments have to be a pointerto a signal set (type `C<sigset_t *>') and a pointer to a signal numbervariable (type `C<int *>'). This event waits until one of the signals inthe signal set occurred. As a result the occurred signal number is stored inthe second additional argument. Keep in mind that the B<Pth> scheduler doesn'tblock signals automatically. So when you want to wait for a signal with thisevent you've to block it via sigprocmask(2) or it will be delivered withoutyour notice. Example: `C<sigemptyset(&set); sigaddset(&set, SIGINT);pth_event(PTH_EVENT_SIG, &set, &sig);>'.=item C<PTH_EVENT_TIME>This is a time point event. The additional argument has to be of typeC<pth_time_t> (usually on-the-fly generated via pth_time(3)). This eventswaits until the specified time point has elapsed. Keep in mind that the valueis an absolute time point and not an offset. When you want to wait for aspecified amount of time, you've to add the current time to the offset(usually on-the-fly achieved via pth_timeout(3)). Example:`C<pth_event(PTH_EVENT_TIME, pth_timeout(2,0))>'.=item C<PTH_EVENT_MSG>This is a message port event. The additional argument has to be of typeC<pth_msgport_t>. This events waits until one or more messages were receivedon the specified message port. Example: `C<pth_event(PTH_EVENT_MSG, mp)>'.=item C<PTH_EVENT_TID>This is a thread event. The additional argument has to be of type C<pth_t>.One of C<PTH_UNTIL_TID_NEW>, C<PTH_UNTIL_TID_READY>, C<PTH_UNTIL_TID_WAITING>or C<PTH_UNTIL_TID_DEAD> has to be OR-ed into I<spec> to specify on whichstate of the thread you want to wait. Example:`C<pth_event(PTH_EVENT_TID|PTH_UNTIL_TID_DEAD, tid)>'.=item C<PTH_EVENT_FUNC>This is a custom callback function event. Three additional argumentshave to be given with the following types: `C<int (*)(void *)>',`C<void *>' and `C<pth_time_t>'. The first is a function pointer toa check function and the second argument is a user-supplied contextvalue which is passed to this function. The scheduler calls thisfunction on a regular basis (on his own scheduler stack, so be verycareful!) and the thread is kept sleeping while the function returnsC<FALSE>. Once it returned C<TRUE> the thread will be awakened. Thecheck interval is defined by the third argument, i.e., the checkfunction is polled again not until this amount of time elapsed. Example:`C<pth_event(PTH_EVENT_FUNC, func, arg, pth_time(0,500000))>'.=back=item unsigned long B<pth_event_typeof>(pth_event_t I<ev>);This returns the type of event I<ev>. It's a combination of the describingC<PTH_EVENT_XX> and C<PTH_UNTIL_XX> value. This is especially useful to knowwhich arguments have to be supplied to the pth_event_extract(3) function.=item int B<pth_event_extract>(pth_event_t I<ev>, ...);When pth_event(3) is treated like sprintf(3), then this function issscanf(3), i.e., it is the inverse operation of pth_event(3). This means thatit can be used to extract the ingredients of an event. The ingredients arestored into variables which are given as pointers on the variable argumentlist. Which pointers have to be present depends on the event type and has tobe determined by the caller before via pth_event_typeof(3).To make it clear, when you constructed I<ev> via `C<ev =pth_event(PTH_EVENT_FD, fd);>' you have to extract it via`C<pth_event_extract(ev, &fd)>', etc. For multiple arguments of an event theorder of the pointer arguments is the same as for pth_event(3). But alwayskeep in mind that you have to always supply I<pointers> to I<variables> andthese variables have to be of the same type as the argument of pth_event(3)required.=item pth_event_t B<pth_event_concat>(pth_event_t I<ev>, ...);This concatenates one or more additional event rings to the event ring I<ev>and returns I<ev>. The end of the argument list has to be marked with aC<NULL> argument. Use this function to create real events rings out of thesingle-event rings created by pth_event(3).=item pth_event_t B<pth_event_isolate>(pth_event_t I<ev>);This isolates the event I<ev> from possibly appended events in the event ring.When in I<ev> only one event exists, this returns C<NULL>. When remaining
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -