📄 pth.3
字号:
.RE.IP "long \fBpth_version\fR(void);" 4.IX Item "long pth_version(void);"This function returns a hex-value `0x\fIV\fR\fI\s-1RR\s0\fR\fIT\fR\fI\s-1LL\s0\fR' which describes thecurrent \fBPth\fR library version. \fIV\fR is the version, \fI\s-1RR\s0\fR the revisions,\&\fI\s-1LL\s0\fR the level and \fIT\fR the type of the level (alphalevel=0, betalevel=1,patchlevel=2, etc). For instance \fBPth\fR version 1.0b1 is encoded as 0x100101.The reason for this unusual mapping is that this way the version number issteadily \fIincreasing\fR. The same value is also available under compile time as\&\f(CW\*(C`PTH_VERSION\*(C'\fR..Sh "Thread Attribute Handling".IX Subsection "Thread Attribute Handling"Attribute objects are used in \fBPth\fR for two things: First stand\-alone/unboundattribute objects are used to store attributes for to be spawned threads.Bounded attribute objects are used to modify attributes of already existingthreads. The following attribute fields exists in attribute objects:.ie n .IP """PTH_ATTR_PRIO""\fR (read\-write) [\f(CW""int""]" 4.el .IP "\f(CWPTH_ATTR_PRIO\fR (read\-write) [\f(CWint\fR]" 4.IX Item "PTH_ATTR_PRIO (read-write) [int]"Thread Priority between \f(CW\*(C`PTH_PRIO_MIN\*(C'\fR and \f(CW\*(C`PTH_PRIO_MAX\*(C'\fR.The default is \f(CW\*(C`PTH_PRIO_STD\*(C'\fR..ie n .IP """PTH_ATTR_NAME""\fR (read\-write) [\f(CW""char *""]" 4.el .IP "\f(CWPTH_ATTR_NAME\fR (read\-write) [\f(CWchar *\fR]" 4.IX Item "PTH_ATTR_NAME (read-write) [char *]"Name of thread (up to 40 characters are stored only), mainly for debuggingpurposes..ie n .IP """PTH_ATTR_DISPATCHES""\fR (read\-write) [\f(CW""int""]" 4.el .IP "\f(CWPTH_ATTR_DISPATCHES\fR (read\-write) [\f(CWint\fR]" 4.IX Item "PTH_ATTR_DISPATCHES (read-write) [int]"In bounded attribute objects, this field is incremented every time thecontext is switched to the associated thread..ie n .IP """PTH_ATTR_JOINABLE""\fR (read\-write> [\f(CW""int""]" 4.el .IP "\f(CWPTH_ATTR_JOINABLE\fR (read\-write> [\f(CWint\fR]" 4.IX Item "PTH_ATTR_JOINABLE (read-write> [int]"The thread detachment type, \f(CW\*(C`TRUE\*(C'\fR indicates a joinable thread,\&\f(CW\*(C`FALSE\*(C'\fR indicates a detached thread. When a thread is detached,after termination it is immediately kicked out of the system instead ofinserted into the dead queue..ie n .IP """PTH_ATTR_CANCEL_STATE""\fR (read\-write) [\f(CW""unsigned int""]" 4.el .IP "\f(CWPTH_ATTR_CANCEL_STATE\fR (read\-write) [\f(CWunsigned int\fR]" 4.IX Item "PTH_ATTR_CANCEL_STATE (read-write) [unsigned int]"The thread cancellation state, i.e., a combination of \f(CW\*(C`PTH_CANCEL_ENABLE\*(C'\fR or\&\f(CW\*(C`PTH_CANCEL_DISABLE\*(C'\fR and \f(CW\*(C`PTH_CANCEL_DEFERRED\*(C'\fR or\&\f(CW\*(C`PTH_CANCEL_ASYNCHRONOUS\*(C'\fR..ie n .IP """PTH_ATTR_STACK_SIZE""\fR (read\-write) [\f(CW""unsigned int""]" 4.el .IP "\f(CWPTH_ATTR_STACK_SIZE\fR (read\-write) [\f(CWunsigned int\fR]" 4.IX Item "PTH_ATTR_STACK_SIZE (read-write) [unsigned int]"The thread stack size in bytes. Use lower values than 64 \s-1KB\s0 with great care!.ie n .IP """PTH_ATTR_STACK_ADDR""\fR (read\-write) [\f(CW""char *""]" 4.el .IP "\f(CWPTH_ATTR_STACK_ADDR\fR (read\-write) [\f(CWchar *\fR]" 4.IX Item "PTH_ATTR_STACK_ADDR (read-write) [char *]"A pointer to the lower address of a chunk of \fImalloc\fR\|(3)'ed memory for thestack..ie n .IP """PTH_ATTR_TIME_SPAWN""\fR (read\-only) [\f(CW""pth_time_t""]" 4.el .IP "\f(CWPTH_ATTR_TIME_SPAWN\fR (read\-only) [\f(CWpth_time_t\fR]" 4.IX Item "PTH_ATTR_TIME_SPAWN (read-only) [pth_time_t]"The time when the thread was spawned.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_TIME_LAST""\fR (read\-only) [\f(CW""pth_time_t""]" 4.el .IP "\f(CWPTH_ATTR_TIME_LAST\fR (read\-only) [\f(CWpth_time_t\fR]" 4.IX Item "PTH_ATTR_TIME_LAST (read-only) [pth_time_t]"The time when the thread was last dispatched.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_TIME_RAN""\fR (read\-only) [\f(CW""pth_time_t""]" 4.el .IP "\f(CWPTH_ATTR_TIME_RAN\fR (read\-only) [\f(CWpth_time_t\fR]" 4.IX Item "PTH_ATTR_TIME_RAN (read-only) [pth_time_t]"The total time the thread was running.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_START_FUNC""\fR (read\-only) [\f(CW""void *(*)(void *)""]" 4.el .IP "\f(CWPTH_ATTR_START_FUNC\fR (read\-only) [\f(CWvoid *(*)(void *)\fR]" 4.IX Item "PTH_ATTR_START_FUNC (read-only) [void *(*)(void *)]"The thread start function.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_START_ARG""\fR (read\-only) [\f(CW""void *""]" 4.el .IP "\f(CWPTH_ATTR_START_ARG\fR (read\-only) [\f(CWvoid *\fR]" 4.IX Item "PTH_ATTR_START_ARG (read-only) [void *]"The thread start argument.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_STATE""\fR (read\-only) [\f(CW""pth_state_t""]" 4.el .IP "\f(CWPTH_ATTR_STATE\fR (read\-only) [\f(CWpth_state_t\fR]" 4.IX Item "PTH_ATTR_STATE (read-only) [pth_state_t]"The scheduling state of the thread, i.e., either \f(CW\*(C`PTH_STATE_NEW\*(C'\fR,\&\f(CW\*(C`PTH_STATE_READY\*(C'\fR, \f(CW\*(C`PTH_STATE_WAITING\*(C'\fR, or \f(CW\*(C`PTH_STATE_DEAD\*(C'\fRThis can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_EVENTS""\fR (read\-only) [\f(CW""pth_event_t""]" 4.el .IP "\f(CWPTH_ATTR_EVENTS\fR (read\-only) [\f(CWpth_event_t\fR]" 4.IX Item "PTH_ATTR_EVENTS (read-only) [pth_event_t]"The event ring the thread is waiting for.This can be queried only when the attribute object is bound to a thread..ie n .IP """PTH_ATTR_BOUND""\fR (read\-only) [\f(CW""int""]" 4.el .IP "\f(CWPTH_ATTR_BOUND\fR (read\-only) [\f(CWint\fR]" 4.IX Item "PTH_ATTR_BOUND (read-only) [int]"Whether the attribute object is bound (\f(CW\*(C`TRUE\*(C'\fR) to a thread or not (\f(CW\*(C`FALSE\*(C'\fR)..PPThe following \s-1API\s0 functions can be used to handle the attribute objects:.IP "pth_attr_t \fBpth_attr_of\fR(pth_t \fItid\fR);" 4.IX Item "pth_attr_t pth_attr_of(pth_t tid);"This returns a new attribute object \fIbound\fR to thread \fItid\fR. Any queries onthis object directly fetch attributes from \fItid\fR. And attribute modificationsdirectly change \fItid\fR. Use such attribute objects to modify existing threads..IP "pth_attr_t \fBpth_attr_new\fR(void);" 4.IX Item "pth_attr_t pth_attr_new(void);"This returns a new \fIunbound\fR attribute object. An implicit \fIpth_attr_init()\fR isdone on it. Any queries on this object just fetch stored attributes from it.And attribute modifications just change the stored attributes. Use suchattribute objects to pre-configure attributes for to be spawned threads..IP "int \fBpth_attr_init\fR(pth_attr_t \fIattr\fR);" 4.IX Item "int pth_attr_init(pth_attr_t attr);"This initializes an attribute object \fIattr\fR to the default values:\&\f(CW\*(C`PTH_ATTR_PRIO\*(C'\fR := \f(CW\*(C`PTH_PRIO_STD\*(C'\fR, \f(CW\*(C`PTH_ATTR_NAME\*(C'\fR := `\f(CW\*(C`unknown\*(C'\fR',\&\f(CW\*(C`PTH_ATTR_DISPATCHES\*(C'\fR := \f(CW0\fR, \f(CW\*(C`PTH_ATTR_JOINABLE\*(C'\fR := \f(CW\*(C`TRUE\*(C'\fR,\&\f(CW\*(C`PTH_ATTR_CANCELSTATE\*(C'\fR := \f(CW\*(C`PTH_CANCEL_DEFAULT\*(C'\fR,\&\f(CW\*(C`PTH_ATTR_STACK_SIZE\*(C'\fR := 64*1024 and\&\f(CW\*(C`PTH_ATTR_STACK_ADDR\*(C'\fR := \f(CW\*(C`NULL\*(C'\fR. All other \f(CW\*(C`PTH_ATTR_*\*(C'\fR attributes areread-only attributes and don't receive default values in \fIattr\fR, because theyexists only for bounded attribute objects..IP "int \fBpth_attr_set\fR(pth_attr_t \fIattr\fR, int \fIfield\fR, ...);" 4.IX Item "int pth_attr_set(pth_attr_t attr, int field, ...);"This sets the attribute field \fIfield\fR in \fIattr\fR to a valuespecified as an additional argument on the variable argumentlist. The following attribute \fIfields\fR and argument pairs canbe used:.Sp.Vb 7\& PTH_ATTR_PRIO int\& PTH_ATTR_NAME char *\& PTH_ATTR_DISPATCHES int\& PTH_ATTR_JOINABLE int\& PTH_ATTR_CANCEL_STATE unsigned int\& PTH_ATTR_STACK_SIZE unsigned int\& PTH_ATTR_STACK_ADDR char *.Ve.IP "int \fBpth_attr_get\fR(pth_attr_t \fIattr\fR, int \fIfield\fR, ...);" 4.IX Item "int pth_attr_get(pth_attr_t attr, int field, ...);"This retrieves the attribute field \fIfield\fR in \fIattr\fR and stores itsvalue in the variable specified through a pointer in an additionalargument on the variable argument list. The following \fIfields\fR andargument pairs can be used:.Sp.Vb 15\& PTH_ATTR_PRIO int *\& PTH_ATTR_NAME char **\& PTH_ATTR_DISPATCHES int *\& PTH_ATTR_JOINABLE int *\& PTH_ATTR_CANCEL_STATE unsigned int *\& PTH_ATTR_STACK_SIZE unsigned int *\& PTH_ATTR_STACK_ADDR char **\& PTH_ATTR_TIME_SPAWN pth_time_t *\& PTH_ATTR_TIME_LAST pth_time_t *\& PTH_ATTR_TIME_RAN pth_time_t *\& PTH_ATTR_START_FUNC void *(**)(void *)\& PTH_ATTR_START_ARG void **\& PTH_ATTR_STATE pth_state_t *\& PTH_ATTR_EVENTS pth_event_t *\& PTH_ATTR_BOUND int *.Ve.IP "int \fBpth_attr_destroy\fR(pth_attr_t \fIattr\fR);" 4.IX Item "int pth_attr_destroy(pth_attr_t attr);"This destroys a attribute object \fIattr\fR. After this \fIattr\fR is nolonger a valid attribute object..Sh "Thread Control".IX Subsection "Thread Control"The following functions control the threading itself and make up the main \s-1API\s0of the \fBPth\fR library..IP "pth_t \fBpth_spawn\fR(pth_attr_t \fIattr\fR, void *(*\fIentry\fR)(void *), void *\fIarg\fR);" 4.IX Item "pth_t pth_spawn(pth_attr_t attr, void *(*entry)(void *), void *arg);"This spawns a new thread with the attributes given in \fIattr\fR (or\&\f(CW\*(C`PTH_ATTR_DEFAULT\*(C'\fR for default attributes \- which means that thread priority,joinability and cancel state are inherited from the current thread) with thestarting point at routine \fIentry\fR; the dispatch count is not inherited fromthe current thread if \fIattr\fR is not specified \- rather, it is initializedto zero. This entry routine is called as `pth_exit(\fIentry\fR(\fIarg\fR))' insidethe new thread unit, i.e., \fIentry\fR's return value is fed to an implicit\&\fIpth_exit\fR\|(3). So the thread can also exit by just returning. Neverthelessthe thread can also exit explicitly at any time by calling \fIpth_exit\fR\|(3). Butkeep in mind that calling the \s-1POSIX\s0 function \fIexit\fR\|(3) still terminates thecomplete process and not just the current thread..SpThere is no \fBPth\fR\-internal limit on the number of threads one can spawn,except the limit implied by the available virtual memory. \fBPth\fR internallykeeps track of thread in dynamic data structures. The function returns\&\f(CW\*(C`NULL\*(C'\fR on error..IP "int \fBpth_once\fR(pth_once_t *\fIctrlvar\fR, void (*\fIfunc\fR)(void *), void *\fIarg\fR);" 4.IX Item "int pth_once(pth_once_t *ctrlvar, void (*func)(void *), void *arg);"This is a convenience function which uses a control variable of type\&\f(CW\*(C`pth_once_t\*(C'\fR to make sure a constructor function \fIfunc\fR is called only onceas `\fIfunc\fR(\fIarg\fR)' in the system. In other words: Only the first call to\&\fIpth_once\fR\|(3) by any thread in the system succeeds. The variable referenced via\&\fIctrlvar\fR should be declared as `\f(CW\*(C`pth_once_t\*(C'\fR \fIvariable-name\fR =\&\f(CW\*(C`PTH_ONCE_INIT\*(C'\fR;' before calling this function..IP "pth_t \fBpth_self\fR(void);" 4.IX Item "pth_t pth_self(void);"This just returns the unique thread handle of the currently running thread.This handle itself has to be treated as an opaque entity by the application.It's usually used as an argument to other functions who require an argument oftype \f(CW\*(C`pth_t\*(C'\fR..IP "int \fBpth_suspend\fR(pth_t \fItid\fR);" 4.IX Item "int pth_suspend(pth_t tid);"This suspends a thread \fItid\fR until it is manually resumed again via\&\fIpth_resume\fR\|(3). For this, the thread is moved to the \fB\s-1SUSPENDED\s0\fR queueand this way is completely out of the scheduler's event handling andthread dispatching scope. Suspending the current thread is not allowed.The function returns \f(CW\*(C`TRUE\*(C'\fR on success and \f(CW\*(C`FALSE\*(C'\fR on errors..IP "int \fBpth_resume\fR(pth_t \fItid\fR);" 4.IX Item "int pth_resume(pth_t tid);"This function resumes a previously suspended thread \fItid\fR, i.e. \fItid\fRhas to stay on the \fB\s-1SUSPENDED\s0\fR queue. The thread is moved to the\&\fB\s-1NEW\s0\fR, \fB\s-1READY\s0\fR or \fB\s-1WAITING\s0\fR queue (dependent on what its state waswhen the \fIpth_suspend\fR\|(3) call were made) and this way again enters theevent handling and thread dispatching scope of the scheduler. Thefunction returns \f(CW\*(C`TRUE\*(C'\fR on success and \f(CW\*(C`FALSE\*(C'\fR on errors..IP "int \fBpth_raise\fR(pth_t \fItid\fR, int \fIsig\fR)" 4.IX Item "int pth_raise(pth_t tid, int sig)"This function raises a signal for delivery to thread \fItid\fR only. When onejust raises a signal via \fIraise\fR\|(3) or \fIkill\fR\|(2), its delivered to an arbitrarythread which has this signal not blocked. With \fIpth_raise\fR\|(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 \fIaction\fR is stillconfigured \fIprocess\fR\-wide. When \fIsig\fR is 0 plain thread checking isperformed, i.e., `\f(CW\*(C`pth_raise(tid, 0)\*(C'\fR' returns \f(CW\*(C`TRUE\*(C'\fR when thread \fItid\fRstill exists in the \fB\s-1PTH\s0\fR system but doesn't send any signal to it..IP "int \fBpth_yield\fR(pth_t \fItid\fR);" 4.IX Item "int pth_yield(pth_t 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 \s-1CPU\s0 bursts, itcan be reasonable to interrupt it explicitly by doing a few \fIpth_yield\fR\|(3) callsto give other threads a chance to execute, too. This obviously is thecooperating part of \fBPth\fR. A thread \fIhas not\fR 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 \s-1CPU\s0bursts into smaller units with this call..SpUsually one specifies \fItid\fR as \f(CW\*(C`NULL\*(C'\fR 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 \fIcoroutines\fR where a thread/routine switches to aparticular cooperating thread. If \fItid\fR is not \f(CW\*(C`NULL\*(C'\fR and points to a \fInew\fRor \fIready\fR thread, it is guaranteed that this thread receives executioncontrol on the next dispatching step. If \fItid\fR is in a different state (thatis, not in \f(CW\*(C`PTH_STATE_NEW\*(C'\fR or \f(CW\*(C`PTH_STATE_READY\*(C'\fR) an error is reported..SpThe function usually returns \f(CW\*(C`TRUE\*(C'\fR for success and only \f(CW\*(C`FALSE\*(C'\fR (with\&\f(CW\*(C`errno\*(C'\fR set to \f(CW\*(C`EINVAL\*(C'\fR) if \fItid\fR specified an invalid or still notnew or ready thread.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -