[APUE]第十二章 线程控制
线程属性:
初始化:
int pthread_attr_init(pthread_attr_t*attr); int pthread_attr_destory(pthread_attr_t*attr);
分离状态属性设置和获取
int pthread_attr_getdetachstate(constpthread_attr_t *attr, int * detachstate); intpthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);
获取线程堆栈大小
int pthread_attr_getstacksize(constpthread_attr_t * attr, size_t * size); intpthread_attr_setstacksize(pthread_attr_t * attr, size_t size);
获得栈末尾大小
int pthread_attr_getguardsize(constpthread_attr_t *attr, size_t *guardsize); intpthread_attr_setguardsize(pthread_attr_t* attr, size_t guardsize);
同步属性:
互斥量:
初始化:
intpthread_mutexattr_init(pthread_mutexattr_t * attr); int pthread_mutexattr_destroy(pthread_mutexattr_t*attr);
互斥量有两个重要的属性
1 是多个进程共享属性
通过
int pthread_mutexattr_getpshared(const pthread_mutexattr_t * attr,int* pshared); int pthread_mutexattr_setpshared(const pthread_mutexattr_t * attr, int pshread);
共享属性有两种类型PTHREAD_PROCESS_PRIVATE、PTHREAD_PROCESS_SHARED
一般都是使用线程共享PTHREAD_PROCESS_PRIVATE,这是一般的情况,也是默认的情况。如果涉及到多个进程共享的时候,就得使用PTHREAD_PROCESS_SHARED来处理
2 是互斥量类型属性
类型属性有4类
PTHREAD_MUTEX_NORMAL:并不做任何特殊的错误检查或死锁检查
PTHREAD_MUTEX_ERRORCHECK:互斥量提供错误检查
PTHREAD_MUTEX_RECURSIVE:对互斥量能多次加锁,但是必须得多次释放锁
PTHREAD_MUTEX_DEFAULT:操作系统实现的时候,会映射成其他类型。
通过函数int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int*type);
获得互斥量的类型
intpthread_mutexattr_settype(const pthread_mutexattr_t *attr, int type)
来设置互斥量的类型
读写锁
初始化和destroy
int pthread_rwlockattr_init(pthread_rwlockattr_t* attr); intpthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
读写锁有进程共享属性
int pthread_rwlockattr_getshared(constpthread_rwlockattr_t *attr, int *type); int pthread_rwlockattr_setpshared(constpthread_rwlockattr_t* attr, int type);
条件变量也是
intpthread_condattr_init(pthread_condattr_t * attr); intpthread_condattr_destroy(pthread_condattr_t* attr);
进程共享属性
int pthread_condattr_getpshared(constpthread_condattr_t* attr, int* type); int pthread_condattr_setpshared(constpthread_condattr_t* attr, int type);
可重入:信号可重入和线程可重入getenv那个例子。
线程私有数据
1 有时候需要维护基于每个线程的数据
2 它提供了让基于进程的接口适应多线程环境的机制。,比如erron
创建键
int pthread_key_create(pthread_key_t *key,void(*destruct)(void*))
key是需要创建的,错放着指向的内存单元,每个线程都可以和这个私有key关联,互不干扰。刚开始创建键的时候,每个线程的数据地址设置为NULL,destruct是私有数据的析构函数。线程退出,并且私有数据不为空的话,就会调用析构函数,如果调用exit _exit _Exit abort的时候不会调用析构函数
取消键与线程私有数据之间的关联。
int pthread_key_delete(pthread_key_t *key);
让线程仅仅初始化依次,如static变量一样
int pthread_once(pthread_once_t *initflag,void(*func)());
多个线程初始化一次func函数(仅仅调用一次)
initflag 必须初始化位PTHREAD_ONCE_INIT
线程获得私有地址或者设置私有地址
int pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t key, constvoid* value);
取消选项:
有两个可取消状态和可取消类型
int pthread_setcancelstate(int state, int*oldstate);
把当前状态设置为state,并把原来的状态保存在oldstate
pthread_cancel调用并不是等待线程终止,在默认情况下,线程在取消请求发出后,还是要继续运行的,知道线程达到某个取消点,取消点是线程检查是否被取消并按照请求进行的动作的一耳光为止
线程启动是默认的取消状态时PTHREAD_CANCEL_ENABLE当状态设置为PTHREAD_CANCEL_DISABLE时,对pthread_cancel的调用并不会杀死进程,相反,取消请求对这个线程来说是处于未决状态的,当取消状态再次编程PTHREAD_CANCEL_ENABLE的时候,线程会在下一个取消点对所有未决的取消请求进行处理。
这里所描述的默认取消类型也是延迟取消,调用pthread_cancel以后,在线程到达取消点之前,并不会出现真正的取消,可以通过调用
int pthread_setcanceltype(int type, int*oldstate)来设置
type可以是:
PTHREAD_CANCEL_ASNCHRONOUS
PTHREAD_CANCEL_DEFERRED