线程

来源:互联网 发布:什么是云计算的基础 编辑:程序博客网 时间:2024/06/02 03:38

在linux平台上,在编译调用了PthreadsAPI的程序时,需要设置 cc -pthread(等价于-lpthread)的编译选项

#include<pthread.h>int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start)(void *),void *arg);  //创建一条新线程void pthread_exit(void *retval);    //终止调用线程,且其返回值可由另一线程通过调用pthread_join()来获取pthread_t pthread_self(void);   //线程id会返回给pthread_create()的调用者,一个线程可以通过pthread_self()来获取自己的线程idint pthread_equal(pthread_t t1,pthread_t t2)    //检查两个进程的id是否相同,如果相等返回非0int pthread_join(pthread_t thread,void **retval);   //等待有thread标识的线程终止,如果已经终止,立即返回,这种操作称为连接,retval将会保存线程终止时返回值的拷贝,即return或pthread_exit()指定的值//向thread参数传入指定线程的标识符,并将该线程记为处于分离状态,一旦线程处于分离状态,就不能使用pthread_join来获取其状态int pthread_detach(pthread_t thread);   如有任一线程调用了exit(),那么所有线程立即终止

线程同步
互斥量是属于pthread_mutex_t类型的变量,在使用之前必须对其初始化
pthread_mutex_t mtx=PTHEAD_MUTEX_INITIALIZER; //静态初始化,保护位于锁定互斥量内的变量

int pthread_mutex_lock(pthread_mutex_t *mutex);     //锁定互斥量int pthread_mutex_unlock(pthread_mutex_t,*mutex);   //解锁互斥量//动态初始化互斥量,参数mutex指定函数执行初始化操作的目标互斥量int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutexattr_t *attr);//摧毁动态分配的互斥量,静态初始化的互斥量则不需要int pthread_mutex_destroy(pthread_mutex_t *mutex);  //互斥量类型PTHREAD_MUTEX_NORMAL    //不具有死锁检测(自检)功能PTHREAD_MUTEX_ERRORCHECK    //对此类互斥量的所有操作都会执行错误检查PTHREAD_MUTEX_PECURSIVE     //递归互斥量维护有一个锁计数器,当锁计数器值降为0时,释放该互斥量//条件变量的数据类型是pthread_cond_t ,下面是静态初始化pthread_cond_t cond=PTHREAD_COND_INITIALIZER;int pthread_cond_signal(pthread_cond_t *cond);  //针对cond所指定的条件变量发送信号(唤醒至少一条遭到阻塞的线程)int pthread_cond_broadcast(pthread_cond_t *cond); //针对cond所指定的条件变量发送信号(唤醒所有遭到阻塞的线程)int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex); //阻塞一线程,直到收到条件变量cond的通知,必须由一个while循环而不是if语句来控制对pthread_cond_wait()的调用//abstime指定一个线程等待条件变量通知时休眠时间的上限int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex,const struct timespec *abstime); //动态分配条件变量int pthread_cond_init(pthead_cond_t *cond,const pthread_condattr_t *attr);//摧毁动态条件变量int pthread_cond_destroy(pthread_cond_t *cond);

线程安全和每线程存储

//实现一次性初始化//利用once_control的状态,可以确保无论有多少线程对pthread_once调用多少次,也只会执行一次由init指向的调用者定义函数int pthread_once(pthread_once_t *once_control,void(*init)(void));//once_control必须是指针,指向初始化为PTHREAD_ONCE_INIT的静态变量pthread_once_t once_var=PTHREAD_ONCE_INIT;//为线程特有数据创建一个新键,并通过key所指向的缓冲区返回给调用者//返回的pthread_key_t类型值只是对全局数组的索引,标记为pthread_keys//数组的每个元素都包含两个字段,第一个字段标记该数组元素是否在用,第二个用于存放针对此键,线程特有数据块的解构函数指针int pthread_key_create(pthread_key_t *key,void (*destructor)(void *));//将value的副本存储与一数据结构中,并将value与调用线程以及key相关联int pthread_setspecific(pthread_key_t key,const void *value);//跟上面的函数相反,返回之前与本线程及给定key的值void *pthread_getspecific(pthread_key_t key);//创建线程局部变量,只需要在全局或静态变量的声明中包含_thread说明符即可//但凡带有这种说明符,每个进程都拥有一份对变量的拷贝,线程局部存储中的变量将一直存在,直到线程终止,届时自动释放这一存储static _thread buf[MAX_ERROR_LEN];

线程的取消

//向由thread指定的线程发送一个取消请求int pthread_cancel(pthread_t thread);//调用线程的取消性状态设置为state所给定的值int pthread_setcancelstate(int state,int *oldstate);//state的值如下PTHREAD_CANCEL_DISABLE      //线程不可取消,如果收到取消请求,则会将请求挂起,直至线程的取消状态置为启用PTHREAD_CANCEL_ENABLE       //线程可以取消,这是新建线程取消性状态的默认值PTHREAD_CANCEL_ASYNCHRONOUS //可能会在任何时点取消线程PTHREAD_CANCEL_DEFERED      //取消请求保持挂起状态,直至到达取消点,这也是新建线程的缺省类型int pthread_setcanceltype(int type,int *oldtype);//产生一个取消点,线程如果已有处于挂起状态的取消请求,那么只要调用该函数,线程就会随之终止void pthread_testcancel(void);//每个线程都可以拥有一个清理函数栈,当线程遭取消时,会沿该栈自顶向下一次执行清理函数,首先会执行最近设置的函数,接着是次新的,以此类推,当执行完所有清理函数后,线程终止//增加清理函数void pthread_clearnup_push(void (*routine)(void *),void *arg);//移除清理函数,如果execute非0,无论如何都会执行清理函数void pthread_cleanup_pop(int execute);#include<signal.h>//获取或/并改变当前的信号掩码,除了所操作的是线程信号掩码外,该函数与sigprocmask()的用法完全相同int pthread_sigmask(int how,const sigset_t *set,sigset_t *oldset);//向同一进程下的另一线程发送信号sig,目标线程有thread标识,因为仅在同一进程中可保证线程id的唯一性,所以无法调用pthead_kill()向其他进程中的线程发送信号int pthread_kill(pthread_t thread,int sig);//向统一进程中的另一线程发送携带数据的信号int pthread_sigqueue(pthread_t thread,int sig,const union sigval value);//等待set所指信号集合中的任一信号的到达,接收该信号,且在sig中将其返回,返回信号编号int sigwait(const sigset_t *set,int *sig);
原创粉丝点击