咱们能够将线程看做为一个依托于进程存在的独立逻辑流,它拥有着独立的线程ID,一组寄存器,栈,调度优先级和策略,信号屏蔽字,errno变量以及线程私有数据.
同时,进程的全部信息对全部线程共享,包括可执行程序的代码,程序的全局内存和堆内存以及文件描述符.
关于全部线程共享进程堆内存的问题我查阅了一些资料.某些blog上说线程在共享堆内存的时候内核是对内存作了同步处理以及读写保护,因此全部的线程共享一个堆也是安全的.
这个问题暂时写在前面,等我翻阅一些资料以后再尝试着解释线程共享堆的机制.安全
线程标识:就像每一个进程都有一个进程ID同样,每一个线程都有一个线程ID,线程ID只有在所属进程的上下文中才有意义.
线程ID是用pthread_t数据类型来表示的,考虑到可移植性问题,咱们使用一个函数对两个线程ID进行比较:函数
#include<pthread.h> int pthread_equal(pthread_t tid1, pthread_t tid2) //返回值:若相等则返回非0,不然返回0. pthread_t pthread_self(void) //返回值:调用线程的线程ID
函数原型:线程
#include<pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t * restrict attr, void *(*start_rtn) (void *) void *restrict arg); //成功则返回0,不然返回错误编号.
参数start_rtn:新建立的线程从start_rtn函数地址开始运行,若是须要向函数传递参数,那么须要把这些参数放入一个结构中,而后把结构的地址做为arg参数传入.指针
函数原型:rest
#include<pthread.h> void pthread_exit(void *rval_ptr)
rval_ptr参数:无类型指针,做为线程结束的返回值.code
当咱们但愿阻塞住并等待某个线程终止的时候能够用pthread_joinblog
#include<pthread.h> int pthread_join(pthread_t thread, void **rval_ptr) //成功则返回0,不然返回错误编号.
若是线程被取消,则rval_ptr参数则为PTHREAD_CANCELED进程
须要注意的是,当调用exit的时候,咱们传入的参数能够是一个复杂结构的指针.同时,这个结构所使用的内存最好在分配在堆上,由于当线程结束时该结构可能已经被释放.内存
函数原型:资源
#include<pthread.h> int pthread_detach(pthread_t thread) //成功则返回0,不然返回错误编号.
调用了pthread_detach函数的线程在终止后存储器资源会被当即收回
函数原型:
#include<pthread.h> int pthread_cancel(pthread_t tid); //成功返回0,失败则返回错误码
目标线程能够选择忽略取消或者控制如何被取消,cancel函数并不等待线程终止,而是仅仅提出请求.
函数原型:
#include<pthread.h> void pthread_cleanup_push(void (*rtn) (void *), void *arg) void pthread_cleanup_pop(int execute)