线程限制
线程属性
#include
int pthread_attr_init(pthread_attr_t *attr);
in pthread_attr_destory(pthread_attr_t *attr);
//分离状态
int pthread_attr_getdetachstate(const pthread_attr_t *restrict attr,int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int *detachstate);
//栈的最低地址
int pthread_attr_getstack(const pthread_attr_t *restrict attr,void **restrict stackaddr,size_t *restrict stacksize);
int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr, size_t stacksize);
//栈的大小
int pthread_attr_getstacksize(const pthread_attr_t*restrict attr,size_t *restrict stacksize);
int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize);
//线程栈末尾之后用以避免栈溢出的扩展内存的大小
iint pthread_attr_getguardsize(const pthread_attr_t *restrict attr,size_t *restrict guardsize);
int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
http://www.cnblogs.com/mydomain/archive/2011/08/14/2138454.htm
线程的分离状态决定一个线程以什么样的方式来终止自己。在上面的例子中,我们采用了线程的默认属性,即为非分离状态(即可结合的,joinable,需要回收),这种情况下,原有的线程等待创建的线程结束;只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。
同步属性
互斥量
#include
int pthread_mutexattr_init(pthread_mutexattr_t *attr);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
//进程共享属性
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr,int *restrict pshared);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared);
//健壮的互斥量属性
int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict attr,int *restrict robust);
int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr,int robust);
//指明与该互斥量相关的 状态在互斥量解锁之前是一致
int pthread_mutex_consistent(pthread_mutex_t *mutex);
//互斥量类型属性
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, int *restrict type);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
读写锁
#include
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
//进程共享属性
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr,int *restrict pshared);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared);
条件变量
#include
int pthread_condattr_init(pthread_condattr_t *attr);
int pthread_condattr_destroy(pthread_condattr_t *attr);
//进程共享属性
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr,int *restrict pshared);
int pthread_condattr_setpshared(pthread_condattr_t *attr,int pshared);
//时钟属性
int pthread_condattr_getclock(const pthread_condattr_t *restrict attr,clockid_t *restrict clock_id);
int pthread_condattr_setclock(pthread_condattr_t *attr,clockid_t clock_id);
屏障
#include
int pthread_barrierattr_init(pthread_barrierattr_t *attr);
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
//进程共享属性
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr,int *restrict pshared);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);
重入
#include
int ftrylockfile(FILE *fp);
void flockfile(FILE *fp);
void funlockfile(FILE *fp);
线程特定数据
#include
int pthread_key_create(pthread_key_t *keyp,void(*destruct)(void *));
int pthread_key_delete(pthread_key_t keyp);
pthread_once_t initflag = PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *initflag, void (*initfn)(void));
void destructor(void *);
pthread_key_t key;
pthread_once_t init_done = PTHREAD_ONCE_INIT;
void thread_init(void)
{
err = pthread_key_create(&key, destructor);
}
int threadfunc(void *arg)
{
pthread_once(&init_done, thread_init);
}
void *pthread_getspecific(pthread_key_t key);
int pthread_setspecific(pthread_key_t key,const void *value)
取消选项
#include
int pthread_setcancelstate(int state, int *oldstate);
void pthread_testcancel(void);
int pthread_setcanceltype(int type, int *oldtype);
线程和信号
#include
int pthread_sigmask(int how,const sigset_t *restrict set,sigset_t *restrict oset);
int sigwait(const sigset_t *restrict set, int *restrict signop);
int pthread_kill(pthread_t thread,int signo);
线程可以通过调用 sigwait 等待一个或多个信号的出现
线程和fork
子进程通过继承整个地址空间的副本,还从父进程那儿继承了每个互斥量、读写锁和条件变 量的状态
如果父进程包含一个以上的线程,子进程在 fork 返回以后,如果紧接着不是马上调 用 exec 的话,就需要清理锁状态
POSIX.1 声明,在 fork 返回和子进程调 用其中一个 exec 函数之间,子进程只能调用异步信号安全的函数,这就限制了在调用 exec 之 前子进程能做什么,但不涉及子进程中锁状态的问题
要清除锁状态,可以通过调用 pthread_atfork 函数建立 fork 处理程序
#include
int pthread_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void));
- prepare fork 处理程序由父进程 在 fork 创建子进程前调用。这个 fork 处理程序的任务是获取父进程定义的所有锁
- parent fork 处理 程序是在 fork 创建子进程以后、返回之前在父进程上下文中调用的。这个 fork 处理程序的任务是对 prepare fork 处理程序获取的所有锁进行解锁
- child fork 处理程序在 fork 返回之前在子进程上下文中调用。与 parent fork 处理程序一样,child fork 处理程序也必须释放 prepare fork 处理程序获取的所有锁。