线程结束方式:
1.pthread_exit //pthread_join
2.从线程执行函数中return //此时效果等价于pthread_exit
3.pthread_cancel //线程可以被取消
4.任何一个线程调用了exit 或者 主线程 (main函数) return都会造成 进程结束
线程资源回收 ---pthread_join
int pthread_cancel(pthread_t thread);
功能:发送取消的请求
参数:thread 表示要发送的线程的tid号
返回值:成功 0失败 错误码
1.pthread_join //需要自己回收 ---线程的属性 (可结合性) --- 一般是子线程 在较短时间内运行完
2.pthread_detach //可分离属性 ---子线程运行很久才结束 --- 设置分离属性
函数:pthread_detach();
int pthread_detach(pthread_t thread);
功能:分离线程
参数:thread 要分离的线程的tid
返回值:成功 0;失败 错误码
总结:
1.创建 -- pthread_create
2.执行 -- 线程执行函数
3.退出 -- pthread_exit
return //线程执行函数中
pthread_cancel
exit() //return 从main
4.资源回收
可结合性 --- pthread_join这种用于线程任务较短,主线程需要关心子线程状态
可分离性 --- pthread_detach子程序执行任务较长,主线程也不需要关心子线程状态
对比 线程 和 进程
1.线程 vs 进程
线程 CPU执行的最小单位
进程 资源分配和任务调度基本单位
2. 各自特点 (优缺点)
1.创建 和 调度
线程创建速度快 调度速度快 发程度 更高
2. 安全性
线程:优点:
共享了进程的数据空间 共享数据方面 方便
缺点:
安全性不好 带来资源竞争 专门的技术 解决资源竞争 --- 互斥 同步
进程 进程空间相互独立 优点:
安全性好
缺点:
进程间共享数据不方便 进程间通信 (管道,信号,共享内存)
3. 编程 线程的复杂程度更高一些;
线程间的资源竞争:
共享资源: 临界资源
临界区 : 访问共享资源(临界资源)那段代码
机制:互斥锁
互斥 排他性 --- 要么不访问 要访问就是一次完整操作 (原子操作)
锁:软件层面上的锁
锁的操作机制 框架:
定义互斥锁 ==》初始化锁 ==》加锁 ==》解锁 ==》销毁
1.定义互斥锁:
pthread_mutex_t mutex;
互斥锁类型 互斥锁变量 内核对象
2.初始化锁
pthread_mutex_init(); //初始化一把锁
3.加锁 加锁加要访问临界资源的地方
pthread_mutex_lock(); 上锁
4.解锁
pthread_mutex_unlock(); 解锁 临界资源访问之后就解开
5.销毁
pthread_mutex_destroy();销毁一把锁
pthread_mutex_init()
功能:初始化 互斥锁
int pthread_mutex_init(
pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
参数:
mutex 就是要初始化的 互斥锁变量
attr 属性 NULL 默认属性 --- 普通锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
参数: mutex //要操作的那把锁
int pthread_mutex_destroy(pthread_mutex_t *mutex); 用完之后锁要销毁,释放空间;
总结:锁是一种线程间的同步机制;
互斥锁:保证线程对共享资源的排他性访问;
保证每个线程访问时的原子操作;
对于互斥锁的静态初始化