📄 pth.pod
字号:
events exists, they form a new event ring which is returned.=item pth_event_t B<pth_event_walk>(pth_event_t I<ev>, int I<direction>);This walks to the next (when I<direction> is C<PTH_WALK_NEXT>) or previews(when I<direction> is C<PTH_WALK_PREV>) event in the event ring I<ev> andreturns this new reached event. Additionally C<PTH_UNTIL_OCCURRED> can beOR-ed into I<direction> to walk to the next/previous occurred event in thering I<ev>.=item pth_status_t B<pth_event_status>(pth_event_t I<ev>);This returns the status of event I<ev>. This is a fast operationbecause only a tag on I<ev> is checked which was either set or stillnot set by the scheduler. In other words: This doesn't check theevent itself, it just checks the last knowledge of the scheduler. Thepossible returned status codes are: C<PTH_STATUS_PENDING> (event isstill pending), C<PTH_STATUS_OCCURRED> (event successfully occurred),C<PTH_STATUS_FAILED> (event failed).=item int B<pth_event_free>(pth_event_t I<ev>, int I<mode>);This deallocates the event I<ev> (when I<mode> is C<PTH_FREE_THIS>) or allevents appended to the event ring under I<ev> (when I<mode> isC<PTH_FREE_ALL>).=back=head2 Key-Based StorageThe following functions provide thread-local storage through unique keyssimilar to the POSIX B<Pthread> API. Use this for thread specific global data.=over 4=item int B<pth_key_create>(pth_key_t *I<key>, void (*I<func>)(void *));This created a new unique key and stores it in I<key>. Additionally I<func>can specify a destructor function which is called on the current threadstermination with the I<key>.=item int B<pth_key_delete>(pth_key_t I<key>);This explicitly destroys a key I<key>.=item int B<pth_key_setdata>(pth_key_t I<key>, const void *I<value>);This stores I<value> under I<key>.=item void *B<pth_key_getdata>(pth_key_t I<key>);This retrieves the value under I<key>.=back=head2 Message Port CommunicationThe following functions provide message ports which can be used for efficientand flexible inter-thread communication.=over 4=item pth_msgport_t B<pth_msgport_create>(const char *I<name>);This returns a pointer to a new message port. If name I<name>is not C<NULL>, the I<name> can be used by other threads viapth_msgport_find(3) to find the message port in case they do not knowdirectly the pointer to the message port.=item void B<pth_msgport_destroy>(pth_msgport_t I<mp>);This destroys a message port I<mp>. Before all pending messages on it arereplied to their origin message port.=item pth_msgport_t B<pth_msgport_find>(const char *I<name>);This finds a message port in the system by I<name> and returns the pointer toit.=item int B<pth_msgport_pending>(pth_msgport_t I<mp>);This returns the number of pending messages on message port I<mp>.=item int B<pth_msgport_put>(pth_msgport_t I<mp>, pth_message_t *I<m>);This puts (or sends) a message I<m> to message port I<mp>.=item pth_message_t *B<pth_msgport_get>(pth_msgport_t I<mp>);This gets (or receives) the top message from message port I<mp>. Incomingmessages are always kept in a queue, so there can be more pending messages, ofcourse.=item int B<pth_msgport_reply>(pth_message_t *I<m>);This replies a message I<m> to the message port of the sender.=back=head2 Thread CleanupsPer-thread cleanup functions.=over 4=item int B<pth_cleanup_push>(void (*I<handler>)(void *), void *I<arg>);This pushes the routine I<handler> onto the stack of cleanup routines for thecurrent thread. These routines are called in LIFO order when the threadterminates.=item int B<pth_cleanup_pop>(int I<execute>);This pops the top-most routine from the stack of cleanup routines for thecurrent thread. When I<execute> is C<TRUE> the routine is additionally called.=back=head2 Process ForkingThe following functions provide some special support for process forkingsituations inside the threading environment.=over 4=item int B<pth_atfork_push>(void (*I<prepare>)(void *), void (*)(void *I<parent>), void (*)(void *I<child>), void *I<arg>);This function declares forking handlers to be called before and afterpth_fork(3), in the context of the thread that called pth_fork(3). TheI<prepare> handler is called before fork(2) processing commences. TheI<parent> handler is called after fork(2) processing completes in the parentprocess. The I<child> handler is called after fork(2) processing completed inthe child process. If no handling is desired at one or more of these threepoints, the corresponding handler can be given as C<NULL>. Each handler iscalled with I<arg> as the argument.The order of calls to pth_atfork_push(3) is significant. The I<parent> andI<child> handlers are called in the order in which they were established bycalls to pth_atfork_push(3), i.e., FIFO. The I<prepare> fork handlers arecalled in the opposite order, i.e., LIFO.=item int B<pth_atfork_pop>(void);This removes the top-most handlers on the forking handler stack which wereestablished with the last pth_atfork_push(3) call. It returns C<FALSE> when nomore handlers couldn't be removed from the stack.=item pid_t B<pth_fork>(void);This is a variant of fork(2) with the difference that the current thread onlyis forked into a separate process, i.e., in the parent process nothing changeswhile in the child process all threads are gone except for the scheduler andthe calling thread. When you really want to duplicate all threads in thecurrent process you should use fork(2) directly. But this is usually notreasonable. Additionally this function takes care of forking handlers asestablished by pth_fork_push(3).=back=head2 SynchronizationThe following functions provide synchronization support via mutual exclusionlocks (B<mutex>), read-write locks (B<rwlock>), condition variables (B<cond>)and barriers (B<barrier>). Keep in mind that in a non-preemptive threadingsystem like B<Pth> this might sound unnecessary at the first look, because athread isn't interrupted by the system. Actually when you have a critical codesection which doesn't contain any pth_xxx() functions, you don't need anymutex to protect it, of course.But when your critical code section contains any pth_xxx() function the chanceis high that these temporarily switch to the scheduler. And this way otherthreads can make progress and enter your critical code section, too. This isespecially true for critical code sections which implicitly or explicitly usethe event mechanism.=over 4=item int B<pth_mutex_init>(pth_mutex_t *I<mutex>);This dynamically initializes a mutex variable of type `C<pth_mutex_t>'.Alternatively one can also use static initialization via `C<pth_mutex_tmutex = PTH_MUTEX_INIT>'.=item int B<pth_mutex_acquire>(pth_mutex_t *I<mutex>, int I<try>, pth_event_t I<ev>);This acquires a mutex I<mutex>. If the mutex is already locked by anotherthread, the current threads execution is suspended until the mutex is unlockedagain or additionally the extra events in I<ev> occurred (when I<ev> is notC<NULL>). Recursive locking is explicitly supported, i.e., a thread is allowedto acquire a mutex more than once before its released. But it then also has bereleased the same number of times until the mutex is again lockable by others.When I<try> is C<TRUE> this function never suspends execution. Instead itreturns C<FALSE> with C<errno> set to C<EBUSY>.=item int B<pth_mutex_release>(pth_mutex_t *I<mutex>);This decrements the recursion locking count on I<mutex> and when it is zero itreleases the mutex I<mutex>.=item int B<pth_rwlock_init>(pth_rwlock_t *I<rwlock>);This dynamically initializes a read-write lock variable of type`C<pth_rwlock_t>'. Alternatively one can also use static initializationvia `C<pth_rwlock_t rwlock = PTH_RWLOCK_INIT>'.=item int B<pth_rwlock_acquire>(pth_rwlock_t *I<rwlock>, int I<op>, int I<try>, pth_event_t I<ev>);This acquires a read-only (when I<op> is C<PTH_RWLOCK_RD>) or a read-write(when I<op> is C<PTH_RWLOCK_RW>) lock I<rwlock>. When the lock is only lockedby other threads in read-only mode, the lock succeeds. But when one threadholds a read-write lock, all locking attempts suspend the current thread untilthis lock is released again. Additionally in I<ev> events can be given to letthe locking timeout, etc. When I<try> is C<TRUE> this function never suspendsexecution. Instead it returns C<FALSE> with C<errno> set to C<EBUSY>.=item int B<pth_rwlock_release>(pth_rwlock_t *I<rwlock>);This releases a previously acquired (read-only or read-write) lock.=item int B<pth_cond_init>(pth_cond_t *I<cond>);This dynamically initializes a condition variable variable of type`C<pth_cond_t>'. Alternatively one can also use static initialization via`C<pth_cond_t cond = PTH_COND_INIT>'.=item int B<pth_cond_await>(pth_cond_t *I<cond>, pth_mutex_t *I<mutex>, pth_event_t I<ev>);This awaits a condition situation. The caller has to follow the semantics ofthe POSIX condition variables: I<mutex> has to be acquired before thisfunction is called. The execution of the current thread is then suspendedeither until the events in I<ev> occurred (when I<ev> is not C<NULL>) orI<cond> was notified by another thread via pth_cond_notify(3). While thethread is waiting, I<mutex> is released. Before it returns I<mutex> isreacquired.=item int B<pth_cond_notify>(pth_cond_t *I<cond>, int I<broadcast>);This notified one or all threads which are waiting on I<cond>. WhenI<broadcast> is C<TRUE> all thread are notified, else only a single(unspecified) one.=item int B<pth_barrier_init>(pth_barrier_t *I<barrier>, int I<threshold>);This dynamically initializes a barrier variable of type `C<pth_barrier_t>'.Alternatively one can also use static initialization via `C<pth_barrier_tbarrier = PTH_BARRIER_INIT(>I<threadhold>C<)>'.=item int B<pth_barrier_reach>(pth_barrier_t *I<barrier>);This function reaches a barrier I<barrier>. If this is the last thread (asspecified by I<threshold> on init of I<barrier>) all threads are awakened.Else the current thread is suspended until the last thread reached the barrierand this way awakes all threads. The function returns (beside C<FALSE> onerror) the value C<TRUE> for any thread which neither reached the barrier asthe first nor the last thread; C<PTH_BARRIER_HEADLIGHT> for the thread whichreached the barrier as the first thread and C<PTH_BARRIER_TAILLIGHT> for thethread which reached the barrier as the last thread.=back=head2 User-Space ContextThe following functions provide a stand-alone sub-API for user-spacecontext switching. It internally is based on the same underlying machinecontext switching mechanism the threads in B<GNU Pth> are based on.Hence these functions you can use for implementing your own simpleuser-space threads. The C<pth_uctx_t> context is somewhat modeled afterPOSIX ucontext(3).The time required to create (via pth_uctx_make(3)) a user-space contextcan range from just a few microseconds up to a more dramatical time(depending on the machine context switching method which is available onthe platform). On the other hand, the raw performance in switching theuser-space contexts is always very good (nearly independent of the usedmachine context switching method). For instance, on an Intel Pentium-IIICPU with 800Mhz running under FreeBSD 4 one usually achieves about260,000 user-space context switches (via pth_uctx_switch(3)) per second.=over 4=item int B<pth_uctx_create>(pth_uctx_t *I<uctx>);This function creates a user-space context and stores it into I<uctx>.There is still no underlying user-space context configured. You stillhave to do this with pth_uctx_make(3). On success, this function returnsC<TRUE>, else C<FALSE>.=item int B<pth_uctx_make>(pth_uctx_t I<uctx>, char *I<sk_addr>, size_t I<sk_size>, const sigset_t *I<sigmask>, void (*I<start_func>)(void *), void *I<start_arg>, pth_uctx_t I<uctx_after>);This function makes a new user-space context in I<uctx> which willoperate on the run-time stack I<sk_addr> (which is of maximumsize I<sk_size>), with the signals in I<sigmask> blocked (ifI<sigmask> is not C<NULL>) and starting to execute with the callI<start_func>(I<start_arg>). If I<sk_addr> is C<NULL>, a stackis dynamically allocated. The stack size I<sk_size> has to be atleast 16384 (16KB). If the start function I<start_func> returns andI<uctx_after> is not C<NULL>, an implicit user-space context switchto this context is performed. Else (if I<uctx_after> is C<NULL>) theprocess is terminated with exit(3). This function is somewhat modeledafter POSIX makecontext(3). On success, this function returns C<TRUE>,else C<FALSE>.=item int B<pth_uctx_switch>(pth_uctx_t I<uctx_from>, pth_uctx_t I<uctx_to>);This function saves the current user-space context in I<uctx_from> forlater restoring by another call to pth_uctx_s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -