基本函数
创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数说明: 第一个参数表示线程id。 第二个参数表示线程参数。 第三个是线程的入口函数,入口函数的返回值必须为void*,且入口函数必须为static。 第四个参数表示线程入口函数的参数,类型为void*。
终止线程
void pthread_exit(void *value_ptr);
参数说明: 如果该参数value_ptr不为NULL,那么,此线程调用pthread_exit函数终止时,线程退出返回的值为*value_ptr。
注意:
- Linux主线程里使用pthread_exit(val)结束时,只会使主线程结束,而由主线程创建的子线程并不会因此结束,他们继续执行。
- Linux主线程使用return结束时,那么子线程也就结束了。
- 如果线程是joinable,可以在函数参数里面传递线程的退出信息给主线程。
连接线程
int pthread_join(pthread_t tid, void **status);
参数说明 第一个参数表示等待线程的id。 第二个参数表示该线程结束时的返回值。
注意:
- 等待终止的线程应该处于joinable(结合)状态,即非DETACHED(分离)状态。
- joinable的线程必须用pthread_join()函数来释放线程所占用的资源,如果没有执行这个函数,那么线程的资源永远得不到释放。
- 一个线程仅允许唯一的一个线程使用pthread_join()等待它的终止,否则后面调用的pthread_join会返回错误。
分离线程
int pthread_detach(pthread_t thread);
参数说明 想要分离的某个线程的tid;
注意:
- 将该线程分离后,此线程结束后,会自动释放其所占资源。
- 一般来说,如果没有用pthread_detach分离的线程,都会使用ptread_join来回收其线程所占资源。
互斥量mutex
互斥量的使用流程一般如下所示:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_init(&mutex,NULL);
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
示例:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
pthread_mutex_t mutex ;
void *print_msg(void *arg){
int i=0;
pthread_mutex_lock(&mutex);
for(i=0;i<15;i++){
printf("output : %d\n",i);
usleep(100);
}
pthread_mutex_unlock(&mutex);
}
int main(int argc,char** argv){
pthread_t id1;
pthread_t id2;
pthread_mutex_init(&mutex,NULL);
pthread_create(&id1,NULL,print_msg,NULL);
pthread_create(&id2,NULL,print_msg,NULL);
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_mutex_destroy(&mutex);
return 1;
}
条件变量cond
条件变量的使用流程如下:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
示例:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *thread1(void *);
void *thread2(void *);
int i=1;
int main(void)
{
pthread_t t_a;
pthread_t t_b;
pthread_create(&t_a,NULL,thread1,(void *)NULL);
pthread_create(&t_b,NULL,thread2,(void *)NULL);
pthread_join(t_a, NULL);
pthread_join(t_b, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
exit(0);
}
void *thread1(void *junk)
{
for(i=1;i<=6;i++)
{
printf("thread1: Line: %d, i = %d\n", __LINE__, i);
pthread_mutex_lock(&mutex);
printf("thread1: lock %d\n", __LINE__);
if(i%3==0)
{
printf("thread1:signal 1 %d\n", __LINE__);
pthread_cond_signal(&cond);
printf("thread1:signal 2 %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n", __FUNCTION__, __LINE__);
sleep(1);
}
pthread_mutex_unlock(&mutex);
printf("thread1: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__);
sleep(1);
}
}
void *thread2(void *junk)
{
while(i<6)
{
printf("thread2: Line: %d, i = %d\n", __LINE__, i);
pthread_mutex_lock(&mutex);
printf("thread2: lock %d\n", __LINE__);
if(i%3!=0)
{
printf("thread2: wait 1 %d\n", __LINE__);
pthread_cond_wait(&cond,&mutex);
printf("thread2: wait 2 %d\n", __LINE__);
}
pthread_mutex_unlock(&mutex);
printf("thread2: unlock %d\n", __LINE__);
printf("%s will sleep 1s in Line: %d \n\n", __FUNCTION__, __LINE__);
sleep(1);
}
}
结果为:
thread1: Line: 29, i = 1
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: Line: 52, i = 1
thread2: lock 54
thread2: wait 1 57
thread1: Line: 29, i = 2
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread1: Line: 29, i = 3
thread1: lock 31
thread1:signal 1 34
thread1:signal 2 36
thread1 will sleep 1s in Line: 37
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: wait 2 59
thread2: unlock 62
thread2 will sleep 1s in Line: 63
thread1: Line: 29, i = 4
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread2: Line: 52, i = 4
thread2: lock 54
thread2: wait 1 57
thread1: Line: 29, i = 5
thread1: lock 31
thread1: unlock 41
thread1 will sleep 1s in Line: 42
thread1: Line: 29, i = 6
thread1: lock 31
thread1:signal 1 34
thread1:signal 2 36
thread1 will sleep 1s in Line: 37
thread1: unlock 41
thread2: wait 2 59
thread2: unlock 62
thread2 will sleep 1s in Line: 63
thread1 will sleep 1s in Line: 42
其余函数
pthread_t pthread_self(void);
int pthread_key_create(pthread_key_t *key,void(*destructor)(void*));
int pthread_setspecific(pthread_key_t key, const void *value);
int pthread_key_delete(pthread_key_t key);
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
int pthread_cancel(pthread_t thread);
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
void pthread_testcancel(void);
void pthread_cleanup_push(void (*routine)(void *), void *arg);
void pthread_cleanup_pop(int execute);
线程属性
线程属性结构体
typedef struct {
int threadAttrStatus;
size_t threadAttrStacksize;
void * threadAttrStackaddr;
size_t threadAttrGuardsize;
int threadAttrDetachstate;
int threadAttrContentionscope;
int threadAttrInheritsched;
int threadAttrSchedpolicy;
struct _Sched_param threadAttrSchedparam;
} pthread_attr_t;
struct _Sched_param {
int sched_priority;
}
线程属性函数
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_destroy(pthread_attr_t *attr);
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr);
int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
int pthread_attr_setschedparam(pthread_attr_t *attr,const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr,struct sched_param *param);
int sched_get_priority_max( int policy );
int sched_get_priority_min( int policy );
|