POSIX线程库API(全)(下)

POSIX线程库API(全)(下)编程

获取线程标识符

请使用 pthread_self(3C) 获取调用线程的 thread identifier。安全

pthread_self 语法

 

pthread_t  pthread_self(void);
#include <pthread.h>



pthread_t tid;



tid = pthread_self();

 

pthread_self 返回值

pthread_self() 返回调用线程的 thread identifier。多线程

 

比较线程 ID

请使用 pthread_equal(3C) 对两个线程的线程标识号进行比较。异步

 

pthread_equal 语法

 

int  pthread_equal(pthread_t tid1, pthread_t tid2);
#include <pthread.h>



pthread_t tid1, tid2;

int ret;



ret = pthread_equal(tid1, tid2);

 

pthread_equal 返回值

若是 tid1 和 tid2 相等,pthread_equal() 将返回非零值,不然将返回零。若是 tid1 或 tid2 是无效的线程标识号,则结果没法预测。async

 

初始化线程

使用 pthread_once(3C),能够在首次调用 pthread_once 时调用初始化例程。之后调用 pthread_once() 将不起做用。ide

 

pthread_once 语法

 

int  pthread_once(pthread_once_t *once_control,

    void (*init_routine)(void));
#include <pthread.h>



pthread_once_t once_control = PTHREAD_ONCE_INIT;

int ret;



ret = pthread_once(&once_control, init_routine);

once_control 参数用来肯定是否已调用相关的初始化例程。函数

 

pthread_once 返回值

pthread_once() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,pthread_once() 将失败并返回相应的值。spa

EINVAL线程

描述: 接口

once_control 或 init_routine 是 NULL。

 

中止执行线程

使用 sched_yield(3RT),可使当前线程中止执行,以便执行另外一个具备相同或更高优先级的线程。

 

sched_yield 语法

 

int  sched_yield(void);
#include <sched.h>



int ret;



ret = sched_yield();

 

sched_yield 返回值

sched_yield() 在成功完成以后返回零。不然,返回 -1,并设置 errno 以指示错误状态。

ENOSYS

描述:

本实现不支持 sched_yield。

 

设置线程的优先级

请使用 pthread_setschedparam(3C) 修改现有线程的优先级。此函数对于调度策略不起做用。

 

pthread_setschedparam 语法

 

int  pthread_setschedparam(pthread_t tid, int policy,

    const struct sched_param *param);
#include <pthread.h>



pthread_t tid;

int ret;

struct sched_param param;

int priority;



/* sched_priority will be the priority of the thread */

sched_param.sched_priority = priority;

policy = SCHED_OTHER;



/* scheduling parameters of target thread */

ret = pthread_setschedparam(tid, policy, &param);

 

pthread_setschedparam 返回值

pthread_setschedparam() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下任一状况,pthread_setschedparam() 函数将失败并返回相应的值。

EINVAL

描述:

所设置属性的值无效。

ENOTSUP

描述:

尝试将该属性设置为不受支持的值。

 

获取线程的优先级

pthread_getschedparam(3C) 可用来获取现有线程的优先级。

 

pthread_getschedparam 语法

 

int  pthread_getschedparam(pthread_t tid, int policy,

    struct schedparam *param);
#include <pthread.h>



pthread_t tid;

sched_param param;

int priority;

int policy;

int ret;



/* scheduling parameters of target thread */

ret = pthread_getschedparam (tid, &policy, &param);



/* sched_priority contains the priority of the thread */

priority = param.sched_priority;

 

pthread_getschedparam 返回值

pthread_getschedparam() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,该函数将失败并返回对应的值。

ESRCH

描述:

tid 指定的值不引用现有的线程。

 

向线程发送信号

请使用 pthread_kill(3C) 向线程发送信号。

 

pthread_kill 语法

 

int  pthread_kill(thread_t tid, int sig);
#include <pthread.h>

#include <signal.h>



int sig;

pthread_t tid;

int ret;



ret = pthread_kill(tid, sig);

pthread_kill() 将信号 sig 发送到由 tid 指定的线程。tid 所指定的线程必须与调用线程在同一个进程中。sig 参数必须来自 signal(5) 提供的列表。

若是 sig 为零,将执行错误检查,但并不实际发送信号。此错误检查可用来检查 tid 的有效性。

 

pthread_kill 返回值

pthread_kill() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下任一状况,pthread_kill() 将失败并返回相应的值。

EINVAL

描述:

sig 是无效的信号量。

ESRCH

描述:

当前的进程中找不到 tid。

 

访问调用线程的信号掩码

请使用 pthread_sigmask(3C) 更改或检查调用线程的信号掩码。

 

pthread_sigmask 语法

 

int pthread_sigmask(int how, const sigset_t *new, sigset_t *old);
#include <pthread.h>

#include <signal.h>



int ret;

sigset_t old, new;



ret = pthread_sigmask(SIG_SETMASK, &new, &old); /* set new mask */

ret = pthread_sigmask(SIG_BLOCK, &new, &old); /* blocking mask */

ret = pthread_sigmask(SIG_UNBLOCK, &new, &old); /* unblocking */

how 用来肯定如何更改信号组。how 能够为如下值之一:

  • SIG_BLOCK。向当前的信号掩码中添加 new,其中 new 表示要阻塞的信号组。

  • SIG_UNBLOCK。从当前的信号掩码中删除 new,其中 new 表示要取消阻塞的信号组。

  • SIG_SETMASK。将当前的信号掩码替换为 new,其中 new 表示新的信号掩码。

当 new 的值为 NULL 时,how 的值没有意义,线程的信号掩码不发生变化。要查询当前已阻塞的信号,请将 NULL 值赋给 new 参数。

除非 old 变量为 NULL,不然 old 指向用来存储之前的信号掩码的空间。

 

pthread_sigmask 返回值

pthread_sigmask() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,pthread_sigmask() 将失败并返回相应的值。

EINVAL

描述:

未定义 how 的值。

 

安全地 Fork

请参看法决方案: pthread_atfork中有关 pthread_atfork(3C) 的论述。

 

pthread_atfork 语法

 

int pthread_atfork(void (*prepare) (void), void (*parent) (void),

    void (*child) (void) );

 

pthread_atfork 返回值

pthread_atfork() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,pthread_atfork() 将失败并返回相应的值。

ENOMEM

描述:

表空间不足,没法记录 Fork 处理程序地址。

 

终止线程

请使用 pthread_exit(3C) 终止线程。

 

pthread_exit 语法

 

void  pthread_exit(void *status);
#include <pthread.h>



void *status;



pthread_exit(status); /* exit with status */

pthread_exit() 函数可用来终止调用线程。将释放全部线程特定数据绑定。若是调用线程还没有分离,则线程 ID 和 status 指定的退出状态将保持不变,直到应用程序调用 pthread_join() 以等待该线程。不然,将忽略 status。线程 ID 能够当即回收。有关线程分离的信息,请参见设置分离状态。

 

pthread_exit 返回值

调用线程将终止,退出状态设置为 status 的内容。

 

结束

线程可经过如下方法来终止执行:

  • 从线程的第一个(最外面的)过程返回,使线程启动例程。请参见 pthread_create。

  • 调用 pthread_exit(),提供退出状态。

  • 使用 POSIX 取消函数执行终止操做。请参见 pthread_cancel()

线程的缺省行为是拖延,直到其余线程经过 "joining" 拖延线程确认其已死亡。此行为与非分离的缺省 pthread_create() 属性相同,请参见 pthread_detach。join 的结果是 joining 线程获得已终止线程的退出状态,已终止的线程将消失。

有一个重要的特殊状况,即当初始线程(即调用 main() 的线程)从 main() 调用返回时或调用 exit() 时,整个进程及其全部的线程将终止。所以,必定要确保初始线程不会从 main() 过早地返回。

请注意,若是主线程仅仅调用了 pthread_exit,则仅主线程自己终止。进程及进程内的其余线程将继续存在。全部线程都已终止时,进程也将终止。

 

取消线程

取消操做容许线程请求终止其所在进程中的任何其余线程。不但愿或不须要对一组相关的线程执行进一步操做时,能够选择执行取消操做。

取消线程的一个示例是异步生成取消条件,例如,用户请求关闭或退出正在运行的应用程序。另外一个示例是完成由许多线程执行的任务。其中的某个线程可能最终完成了该任务,而其余线程还在继续运行。因为正在运行的线程此时没有任何用处,所以应当取消这些线程。

 

取消点

仅当取消操做安全时才应取消线程。pthreads 标准指定了几个取消点,其中包括:

  • 经过 pthread_testcancel 调用以编程方式创建线程取消点。

  • 线程等待 pthread_cond_wait 或 pthread_cond_timedwait(3C) 中的特定条件出现。

  •  
  • 被 sigwait(2) 阻塞的线程。

  • 一些标准的库调用。一般,这些调用包括线程可基于其阻塞的函数。有关列表,请参见 cancellation(5) 手册页。

缺省状况下将启用取消功能。有时,您可能但愿应用程序禁用取消功能。若是禁用取消功能,则会致使延迟全部的取消请求,直到再次启用取消请求。

有关禁用取消功能的信息,请参见pthread_setcancelstate 语法。

 

放置取消点

执行取消操做存在必定的危险。大多数危险都与彻底恢复不变量和释放共享资源有关。取消线程时必定要格外当心,不然可能会使互斥保留为锁定状态,从而致使死锁。或者,已取消的线程可能保留已分配的内存区域,可是系统没法识别这一部份内存,从而没法释放它。

标准 C 库指定了一个取消接口用于以编程方式容许或禁止取消功能。该库定义的取消点是一组可能会执行取消操做的点。该库还容许定义取消处理程序的范围,以确保这些处理程序在预期的时间和位置运行。取消处理程序提供的清理服务能够将资源和状态恢复到与起点一致的状态。

必须对应用程序有必定的了解,才能放置取消点并执行取消处理程序。互斥确定不是取消点,只应当在必要时使之保留尽量短的时间。

请将异步取消区域限制在没有外部依赖性的序列,由于外部依赖性可能会产生挂起的资源或未解决的状态条件。在从某个备用的嵌套取消状态返回时,必定要当心地恢复取消状态。该接口提供便于进行恢复的功能:pthread_setcancelstate(3C) 在所引用的变量中保留当前的取消状态,pthread_setcanceltype(3C) 以一样的方式保留当前的取消类型。

在如下三种不一样的状况下可能会执行取消操做:

  • 异步

  • 执行序列中按标准定义的各个点

  • 调用 pthread_testcancel()

缺省状况下,仅在 POSIX 标准可靠定义的点执行取消操做。

不管什么时候,都应注意资源和状态恢已复到与起点一致的状态。

 

取消线程

请使用 pthread_cancel(3C) 取消线程。

 

pthread_cancel 语法

 

int pthread_cancel(pthread_t thread);
#include <pthread.h>



pthread_t thread;

int ret;



ret = pthread_cancel(thread);

取消请求的处理方式取决于目标线程的状态。状态由如下两个函数肯定:pthread_setcancelstate(3C) 和 pthread_setcanceltype(3C)。

 

pthread_cancel 返回值

pthread_cancel() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,该函数将失败并返回对应的值。

ESRCH

描述:

没有找到与给定线程 ID 相对应的线程。

 

启用或禁用取消功能

请使用 pthread_setcancelstate(3C) 启用或禁用线程取消功能。建立线程时,缺省状况下线程取消功能处于启用状态。

 

pthread_setcancelstate 语法

 

int pthread_setcancelstate(int state, int *oldstate);
#include <pthread.h>



int oldstate;

int ret;



/* enabled */

ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);



/* disabled */

ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);

 

pthread_setcancelstate 返回值

pthread_setcancelstate() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,pthread_setcancelstate() 函数将失败并返回相应的值。

EINVAL

描述:

状态不是 PTHREAD_CANCEL_ENABLE 或 PTHREAD_CANCEL_DISABLE。

 

设置取消类型

使用 pthread_setcanceltype(3C) 能够将取消类型设置为延迟或异步模式。

 

pthread_setcanceltype 语法

 

int pthread_setcanceltype(int type, int *oldtype);
#include <pthread.h>



int oldtype;

int ret;



/* deferred mode */

ret = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);



/* async mode*/

ret = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);

建立线程时,缺省状况下会将取消类型设置为延迟模式。在延迟模式下,只能在取消点取消线程。在异步模式下,能够在执行过程当中的任意一点取消线程。所以建议不使用异步模式。

 

pthread_setcanceltype 返回值

pthread_setcanceltype() 在成功完成以后返回零。其余任何返回值都表示出现了错误。若是出现如下状况,该函数将失败并返回对应的值。

EINVAL

描述:

类型不是 PTHREAD_CANCEL_DEFERRED 或 PTHREAD_CANCEL_ASYNCHRONOUS。

 

建立取消点

请使用 pthread_testcancel(3C) 为线程创建取消点。

 

pthread_testcancel 语法

 

void pthread_testcancel(void);
#include <pthread.h>



pthread_testcancel();

当线程取消功能处于启用状态且取消类型设置为延迟模式时,pthread_testcancel() 函数有效。若是在取消功能处于禁用状态下调用 pthread_testcancel(),则该函数不起做用。

请务必仅在线程取消操做安全的序列中插入 pthread_testcancel()。除经过 pthread_testcancel() 调用以编程方式创建的取消点之外,pthread 标准还指定了几个取消点。有关更多详细信息,请参见取消点。

 

pthread_testcancel 返回值

pthread_testcancel() 没有返回值。

 

将处理程序推送到栈上

使用清理处理程序,能够将状态恢复到与起点一致的状态,其中包括清理已分配的资源和恢复不变量。使用 pthread_cleanup_push(3C) 和 pthread_cleanup_pop(3C) 函数能够管理清理处理程序。

在程序的同一词法域中能够推送和弹出清理处理程序。推送和弹出操做应当始终匹配,不然会生成编译器错误。

 

pthread_cleanup_push 语法

 

请使用 pthread_cleanup_push(3C) 将清理处理程序推送到清理栈 (LIFO)。

void pthread_cleanup_push(void(*routine)(void *), void *args);
#include <pthread.h>



/* push the handler "routine" on cleanup stack */

pthread_cleanup_push (routine, arg);

 

pthread_cleanup_push 返回值

pthread_cleanup_push() 没有返回值。

 

从栈中弹出处理程序

请使用 pthread_cleanup_pop(3C) 从清理栈中弹出清理处理程序。

 

pthread_cleanup_pop 语法

 

void pthread_cleanup_pop(int execute);
#include <pthread.h>



/* pop the "func" out of cleanup stack and execute "func" */

pthread_cleanup_pop (1);



/* pop the "func" and DONT execute "func" */

pthread_cleanup_pop (0);

若是弹出函数中的参数为非零值,则会从栈中删除该处理程序并执行该处理程序。若是该参数为零,则会弹出该处理程序,而不执行它。

线程显式或隐式调用 pthread_exit(3C) 时,或线程接受取消请求时,会使用非零参数有效地调用 pthread_cleanup_pop()

 

pthread_cleanup_pop 返回值

pthread_cleanup_pop() 没有返回值。

相关文章
相关标签/搜索