gcc编译时候需要加 -lpthread (gcc *.c -lpthread)
头文件则需要添加 #include<pthread.h>
了解线程的每个原语,有助于对多线程编程透彻的理解
创建线程
Pthread_create(pthred_t *thread, const pthread_attr_t *attr, void* (*start_routine)(void *), void *arg);
pthred_t*thread 传出参数 保存线程ID
constpthread_attr_t *attr 线程属性(1M,2M…) 默认属性(NULL),设置线程栈大小, 设置线程优先级
void*(start_routine)(void ) 函数指针, 执行这个函数
void*arg 传的是上一个函数指针的参数
成功返回0 , 失败返回错误码
获取线程ID
pthread_serf(void);
pthread_t pthread_self() 不能说完全等价 pthread_create 创建线程函数的第一个参数
因为pthread_create函数是三步 1. 先创建线程 2. 线程号填写回给tid 3.返回函数调用
1、 有可能线程创建成功,然后cpu调度执行了该线程,线程退出后,然后才填写tid,tid已经没用。
2、 有可能创建完线程,还没填写tid,某个信号捕捉函数里使用刚才创建的tid,但是tid值没用(垃圾值)
打印创建错误信息
fprintf(stderr,"%s", strerror(线程创建失败的返回值));
线程终止, 线程退出函数
任何一个线程调用了exit或者_exit函数都会终止整个进程(或者主函数调用了return)
pthread_exit(void*retval) 传出值
注意
:pthread_exit 或者 return 返回的指针所指向的内存单元必须是全局或者malloc 分配的, 不能是线程函数的栈上分配,,因为当其他线程得到这个返回指针的时候线程函数已经退出了,线程栈被释放
等待线程(类比进程wait)
阻塞等待回收线程的退出值并且释放其PCB
如果没有调用,则会出现“僵尸线程”
IntPthread_join(pthread_t thread, void **retval)
Pthread_tthread 指定回收线程id
Void**retval 接收退出线程传递出的返回值
返回值:成功返回0 , 失败返回错误号
如果thread线程return返回,retval指向空间存放的是thread线程函数的返回值(pthread_create函数的第三个参数,即回调函数的返回值)
如果thread线程被别的线程调用pthread_cancel异常终止, 则retval指向空间存的是常数PTHREAD_CANCELED
如果thread线程自己调用pthread_exit终止,retval指向空间存的是传给pthread_exit的参数
如果对thread线程终止状态不感兴趣,retval可以设置为NULL
取消线程
在进程内 某个线程可以取消另一个线程
Intpthread_cancel(pthread_t thread)
被取消的线程 退出值 定义在Linux的pthread库中常数PTHREAD_CANCELED的值是-1 ,可在头文件pthread.h中找到他的定义(/usr/include/pthread.h)
设置线程分离态
创建线程后,如果不关心其返回值,则可将其设置(pthread_detach)为分离态线程(不用pthread_join等待),不用主控线程回收资源,操作系统自动回收
IntPthread_detach(pthread_t tid);
Pthread_ttid:分离线程tid
返回值:成功返回0 失败返回错误码
如果pthread_join一个 detach的线程, 则会调用失败返回EINVAL(无效)
两个函数互斥
比较线程是否相等
Intpthread_equal(pthread_t tid1, pthread_ttid2)
线程原语函数通常:
成功:返回0
失败:返回错误码