线程
?
创建一个缺省的线程
缺省的线程的属性:
l???????? 非绑定
l???????? 未分离
l???????? 一个缺省大小的堆栈
l???????? 具有和父线程一样的优先级
? ?
用 phread_attr_init() 创建一个缺省的属性对象,
用属性对象创建一个线程 pthread_create(3T)
? ?
int p thread_create ( pthread_t *tid, const pthread_attr_t *tattr, void *(*start_routine)(void*), void *arg );
? ?
#include<pthread.h>
pthread_attr_t? tattr;
pthread_t? tid;
extern? void? *start_routine(void *arg);
void? *arg;
int? ret;
? ?
/*default behavior*/
ret = pthread_create( &tid, NULL, start_routine, arg );
? ?
/*init with default attributes*/
ret = pthread_attr_init( &tattr );
? ?
/*default behavior specified*/
ret = pthread_create( &tid, &tattr, start_routine, arg );
? ?
tattr 中含有初始化线程所需的属性,值赋为 NULL 即缺省。 start_routine 是线程入口函数的起始地址。当 start_routine 返回时,相应的线程就结束了。线程结束时的退出状态值是 start_routine 函数用 phread_exit() 函数返回的返回值。当 pthread_create() 函数调用成功时,线程标识符保存在参数 tid 指针指向中。
返回值, pthread_create() 成功后返回 0 ,
EAGAIN 超过了某个限制,如 LWPs 过多。
EINVAL?? tattr 值非法。
? ?
创建子线程时,传给子线程的输入参数最好是 malloc() 返回的指针(这样的指针指向进程堆中的存储空间)或指向全局变量的指针,而不要是指向局部变量的指针。因为当子线程访问输入参数时,创建子线程的函数可能已结束,局部变量也就不存在了。
? ?
等待线程结束
?????? pthread_join(3T)
?????? int pthread_join( pthread_t tid, void **status );
?????? #include<pthread.h>
? ?
?????? pthread_t? tid;
?????? int? ret;
?????? int? status;
? ?
?????? /*waiting to join thread "tid" with status*/
?????? ret = pthread_join( tid, &status );
? ?
?????? /*waiting to join thread "tid" without status*/
?????? ret = pthread_join( tid, NULL );
? ?
?????? pthread_join() 会阻塞调用它的线程,直到参数 tid 指定的线程结束。 tid 指定的线程必须在当前进程中,且必须是非分离的。 status 接收指定线程终止时的返回状态码。
?????? 不能有多个线程等待同一个线程终止,否则返回错误码 ESRCH
?????? 当 pthread_join() 返回时,终止线程占用的堆栈等资源已被回收。
?????? 返回值:成功返回 0
?????? ESRCH? tid 指定的线程不是一个当前线程中合法且未分离的线程。
?????? EDEADLK? tid 指定的是当前线程。
?????? EINVAL? tid 非法。
? ?
分离一个线程
?????? pthread_detach(3T)
?????? 将非分离线程设置为分离线程。
? ?
?????? int? pthread_detach( pthread_t tid );
?????? #include<pthread.h>
?????? pthread_t? tid;
?????? int? ret;
?????? ret = pthread_detach( tid );
? ?
?????? 该函数通知线程库,当线程终止以后, tid 所指线程的内存可以被立即收回。
?????? 返回值:成功返回 0
?????? EINVAL? tid 所指线程不是一个合法线程。
?????? ESRCH? tid 指定的线程不是一个当前线程中合法且未分离的线程。
? ?
为线程数据创建一个键
?????? 多线程的 c 语言程序具有三种数据:局部变量,全局变量,线程数据( TSD )
?????? TSD 类似于全局变量,但是线程私有的 。
?????? 每个 TSD 都有个键同他相关联。
?????? pthread_key_create(3T)
? ?
?????? int pthread_key_create( pthread_key_t *key, void (*destructor)(*void) );
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? int? ret;
?????? /*key create without destructor*/
?????? ret = pthread_key_create( &key, NULL );
? ?
?????? /*key create with destructor*/
?????? ret = pthread_key_destructor( &key, destructor );
? ?
?????? 该函数成功时,份配的建放在 key 中,必须保证 key 指向的内存区有效 。 destructor 用来释放不再需要的内存。
?????? 返回值:成功返回 0
?????? EAGAIN? key 名字空间耗尽
?????? ENOMEM? 没有足够的内存空间创建一个新的键。
? ?
删除线程数据的键
?????? pthread_key_delete(3T)
?????? solaris 线程接口中没有该函数
? ?
?????? int pthread_key_delete ( pthread_key_t key );
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? int? ret;
?????? ret = pthread_key_delete( key );
? ?
?????? 在调用该函数之前,必须释放和本线程相关联的资源, pthread_key_delete() 不会引发键的解析函数。
?????? 返回值:成功返回 0
?????? EINVAL? key 值非法
? ?
设置线程数据键
?????? pthread_setspecific(3T)
?????? 设置和某个线程数据键绑定在一起的线程数据 (一般是指针)
?????? 函数将指向专有数据的指针value 设置进? 由key指示的结构体 中;
?????? int? pthread_setspecific ( pthread_key_t key, const void *value );
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? void *value;
?????? int? ret;
?????? ret = pthread_setspecific( key, value );
? ?
?????? 返回值:成功返回 0
?????? ENOMEM? 没有足够的虚拟内存
?????? EINVAL? key 值非法
?????? pthread_setspecific() 不释放原来绑定在键上的内存,给一个键绑定新的指针时,必须释放原指针指向的内存 ,否则会发生内存泄漏。
? ?
获取线程数据键
?????? pthread_getspecific(3T)
?????? 获取绑定在线程数据键上的值,并在指定的位置存储值
?????? 返回存放在对应结构体中的专有指针;
?????? int? pthread_getspecific( pthread_key_t key, void**value )
?????? #include<pthread.h>
?????? pthread_key_t? key;
?????? void? *value;
?????? pthread_getspecific( key, &value );
? ?
?????? 返回值:不返回错误码
? ?
取线程标识符
?????? pthread_self(3T)
?????? 取当前线程的标识符
? ?
?????? pthread_t? pthread_self( void );
?????? #include<pthread.h>
?????? pthread_t? tid;
?????? tid = pthread_self();
? ?
?????? 返回值:当前线程标识符。
? ?
比较线程标识符
?????? pthread_equal(3T)
? ?
?????? int? pthread_equal( pthread_t tid1, pthread_t tid2 );
?????? #include<pthread.h>
?????? pthread_t? tid1,tid2
?????? int? ret;
?????? ret = pthread_equal( tid1, tid2 );
? ?
?????? 返回值:如果 tid1 和 tid2 相同返回非零值,否则返回 0 。如果参数非法,返回值不可预知。
? ?
初始化线程
?????? pthread_once(3T)
?????? 用来调用初始化函数,只有第一次调用有效。
?????? 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 界定了相应的初始化函数是否被调用过。
?????? 返回值:成功返回 0
?????? EINVAL? 某个参数为 NULL
? ?
出让当前线程对处理器的控制权
?????? sched_yeild(3R)
?????? 把当前线程的优先权让给有相同或更高优先级的线程。
?????? int? sched_yeild( void );
?????? #include<pthread.h>
?????? int? ret;
?????? ret = sched_yeild();
? ?
?????? 返回值:成功返回 0
?????? ENOSYS? 当前版本不支持 sched_yield()
? ?
设置线程的优先级
?????? pthread_setschedparam(3T)
? ?
?????? 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;
?????? /*only supported policy ,other will result in ENOTSUP*/
?????? policy = SCHED_OTHER;
?????? /*scheduling parameters of target thread*/
?????? ret = pthread_setschedparam( tid, policy, ¶m );
? ?
?????? 返回值:成功返回 0
EINVAL? 属性值非法
ENOTSUP? 属性值在当前版本不支持
? ?
取线程的优先级
?????? pthread_getschedparam(3T)
? ?
?????? int? pthread_getschedparam( pthread_t tid, int policy, struct schedparam *param );
?????? #include<pthread.h>
?????? pthread_t? tid;
?????? sched_param? param;
?????? int? prioprity;
?????? int? policy;
?????? int? ret;
?????? /*scheduling parameters of target thread*/
?????? ret = pthread_getschedparam( tid, &policy, ¶m );
?????? /*sched_priority contains the priority of the thread*/
?????? priority = param.sched_priority;
? ?
?????? 返回值:成功返回 0
?????? ESRCH? tid 不是一个现存的线程。
? ?
向线程发信号
?????? pthread_kill(3T)
? ?
?????? int? pthread_kill( pthread_t tid, int sig );
?????? #include<pthread.h>
?????? #include<signal.h>
?????? int? sig;
?????? pthread_t? tid;
?????? int? ret;
?????? ret = pthread_kill( tid, sig );
? ?
?????? tid 指定的线程必须和函数当前线程在同一个进程中。
?????? sig 为 0 时,进行错误检查,不发送信号,往往被用来检查 tid 的合法性。
?????? 返回值:成功返回 0
?????? EINVAL? sig 不是合法信号量
?????? ESRCH? tid 不是当前进程中的线程
? ?
访问当前线程的信号掩码
?????? pthread_sigmask(3T)
? ?
?????? 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 );
?????? ret = pthread_sigmask( SIG_BLOCK, &new, &old );
ret = pthread_sigmask( SIG_UNBLOCK, &new, &old );
? ?
?????? how 表示对当前信号掩码进行什么操作。
????????????? SIG_SETMASK :在信号掩码中加入 new 信号集, new 表示新增加的要屏蔽的信号。
????????????? SIG_BLOCK :在信号掩码中删去 new 信号集, new 表示新增加的不需再屏蔽的信号。
????????????? SIG_UNBLOCK :用 new 信号集替换信号掩码, new 表示所有需要屏蔽的信号。
?????? 当 new 为 NULL 时,无论 how 是什么,当前线程的信号掩码都不会改变。
?????? 旧的信号掩码保存在 old 中。
?????? 返回值:成功返回 0
?????? EINVAL? how 的值未定义
? ?
安全的复制
?????? pthread_atfork(3T)
? ?
?????? int? pthread_atfork( void(*prepare)(void), void(*parent)(void), void(*child)(void) );
? ?
终止线程
?????? pthread_exit(3T)
? ?
?????? void? pthread_exit(void *status);
?????? #include<pthread.h>
?????? int? status;
?????? pthread_exit( &status );
? ?
?????? 终止当前线程,所有绑定在线程键上的内存将释放。如果当前线程是未分离的,该线程的标识符和推出代码( status )被保留,直到其它线程用 pthread_join() 等待当前线程的终止。如果当前线程是分离的, status 被忽略,线程标识符立即收回。
?????? 返回值:若 status 不为 NULL ,线程的退出代码被置为 status 指向的值。
? ?
?????? 一个线程可以用一下方式终止自身运行。
?????? 从线程的入口函数返回。
?????? 调用 pthread_exit()
?????? 用 POSIX 的 pthread_cancel()
? ?
?????? 退出可以用以下方式:
?????? 异步的
?????? 由线程库定义的一系列退出点
?????? 有应用程序定义的一系列退出点
? ?
?????? 退出点
?????? 由程序通过 pthread_testcancel() 建立
?????? 调用了 pthread_cond_wait() 或 pthread_cond_timedwait() 等待一个条件的线程
?????? 调用了 pthread_join() 等待另一个线程结束的线程。
?????? 被阻塞在 sigwait(2) 上的线程。
?????? 一些标准的库函数。
? ?
退出线程
?????? pthread_cancel(3T)
? ?
?????? int? pthread_cancel( pthread_t thread );
#include<pthread.h>
pthread_t? thread;
int? ret;
ret = pthread_cancel ( thread ) ;
? ?
返回值:成功返回 0
ESRCH? 无指定的线程。
? ?
允许或禁止退出
?????? pthread_setcancelstate(3T)
?????? 缺省是允许退出的。
?????? int? pthread_setcancelstate( int state, int *oldstate );
?????? #include<pthread.h>
?????? int? oldstate;
?????? int? ret;
?????? /*enable*/
?????? ret = pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
?????? /*disabled*/
ret = pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
? ?
返回值:成功返回 0
EINVAL? state 值非法
? ?
设置退出类型
?????? pthread_setcanceltype(3T)
?????? 可以设置成延迟类型或异步类型。缺省是延迟类型。异步类型下,线程可以在执行中的任何时候被退出。
?????? 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 );
? ?
返回值:成功返回 0
EINVAL? state 值非法
? ?
创建退出点
?????? pthread_testcancel(3T)
?????? void? pthread_testcancel( void );
?????? #include<pthread.h>
?????? pthread_testcancel();
? ?
?????? 只有当线程的退出状态是允许退出,退出类型是延迟类型时,有效。
?????? 没有返回值。
? ?
将一个善后处理函数推入退出堆栈
?????? pthread_cleanup_push(3T)
?????? pthread_cleanup_pop(3T)
? ?
?????? void Pthread_cleanup_push( void(*routine)(void*), void *args );
?????? void pthread_cleanup_pop( int execute );
?????? #include<pthread.h>
?????? /*push the handler "routine" on cleanup stack*/
?????? pthread_cleanup_push( routine, arg );
?????? /*pop the "func" out of cleanup stack and execute "func"*/
?????? pthread_cleanup_pop( 1 );
?????? /*pop the "func" and don‘t execute "func"*/
?????? pthread_cleanup_pop( 0 );
? ?
? ?
1.????????? 线程属性
只能在线程创建时制定属性,不能在运行时改变它。
一旦属性对象被配置好,它在进程范围内都是有效的。
? ?
初始化属性
pthread_attr_init(3T)
?????? 初始化一个线程属性对象,属性值是缺省值,占用内存由线程库分配。
?????? int? pthread_attr_init( pthread_attr_t *tattr );
?????? #include<pthread.h>
?????? pthread_attr_t? tattr;
?????? int? ret;
?????? /*initialize an attribute to the default value*/
?????? ret = pthread_attr_init( &tattr );
? ?
?????? 属性对象的缺省值:
?????? scope (线程域)??????? PTHREAD_SCOPE_PROCESS
?????? Detachstate (分离状态)?? PTHREAD_CREATE_JOINABLE
?????? Stackaddr (堆栈地址)?? NULL
?????? Stacksize (堆栈大小)?? 1Mb
?????? priority (优先级)?? 父进程优先级
?????? Inheritsched (继承调度优先级)?? PTHREAD_INHERIT_SCHED
?????? schedpolicy (调度策略)?? SCHED_OTHER
? ?
?????? 返回值:成功返回 0
?????? ENOMEM? 没有足够的内存初始化线程属性对象
? ?
释放属性对象
pthread_attr_destroy(3T)
? ?
?????? int? pthread_attr_destroy( pthread_attr_t *tattr? );
?????? #include<pthread.h>
?????? pthread_attr_t? tattr;
?????? int? ret;
?????? ret = pthread_attr_destroy( &tattr );
? ?
?????? 返回值:成功返回 0
?????? EINVAL? tattr 值非法
? ?
设置分离状态
pthread_attr.setdetachstate(3T)
?????? 创建线程时,如果指定这个线程为分离线程,一旦这个线程终止,他的线程标识符和其他相关的资源可以立即被使用。如果不需要等待某个线程终止,可以把它设定为分离。
int? pthread_attr_setdetachstate( pthread_attr_t *tattr, int detachstate );
#include<pthread.h>
?????? pthread_attr_t? tattr;
?????? int? ret;
?????? /*set the thread detach state*/
?????? ret = pthread_attr_setdetachstate( &tattr, PTHREAD_CREATE_DETACHED );
? ?
?????? 返回值:成功返回 0
?????? EINVAL? tattr 的值或 detachstate 的值非法
? ?
取分离状态
pthread_attr_getdetachstate(3T)
?????? int? pthread_attr_getdetachstate( const pthread_attr_t *tattr, int *detachstate );
?????? #include<pthread.h>
?????? pthread_attr_t? tattr;
?????? int? detachstate;
?????? int? ret;
?????? ret = pthread_attr_getdetachstate( &tattr,? &detachstate );
? ?
?????? 返回值:成功返回 0
?????? EINVAL? tattr 的值或 detachstate 的值非法
原文:http://www.cnblogs.com/kissiey/p/4361442.html