一、线程的退出
1、上篇介绍的pthread_exit
2、从线程执行函数中return;
3、pthread_cancel
int pthread_cancel(pthread_t thread(要发送的线程tid))
功能:发送取消的请求。
4、任何一个线程调用了exit;或者主线程(main函数)return;都会造成进程结束。
二、退出时资源的回收
1、上篇介绍的pthread_join,自己回收
线程属性为<可结合性>用。一般是子线程在较短时间内运行完,主线程需要关心子线程状态。
2、pthread_detach
int pthread_detach(pthread_t rhread(要分离线程tid))
功能:分离线程
可分离属性时,子线程运行很久才结束,设置分离线程;主线程不需要关心子线程。
三、线程与进程对比
四、资源竞争解决技术
1、互斥锁
共享资源也称临界资源;临界区则是访问共享资源(临界资源)的那一段代码。
互斥锁机制具有排他性,要么不访问,要访问就是一次完整的操作(原子操作)。
步骤:定义互斥锁——>初始化锁——>加锁——>解锁——>销毁。
(1)定义互斥锁
pthread_mutex_t(互斥锁类型) mutex(互斥锁变量(内核对象))
(2)初始化锁
动态初始化:
int pthread_mutex_init(pthread_mutex_t *restrict mutex(要初始化锁的变量) , const pthread_mutexattr_t *restrict attr(属性,NULL为默认属性——普通锁))
静态初始化:(定义+初始化)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
(3)加锁
加在要访问临界资源的地方。
int pthread_mutex_lock(pthread_mutex_t *mutex(要操作的那把锁))
lock在没有要锁的资源时,会持续等待。
int pthread_mutex_trylock(pthread_mutex_t *mutex
lock在没有要锁的资源时,会返回。因此非阻塞要重新锁时,要加入循环。
(4)解锁
临界资源访问之后解锁。
int pthread_mutex_unlock(pthread_mutex_t *mutex)
(5)销毁
int pthread_mutex_destroy(pthread_mutex_t *mutex)
2、死锁
(1)死锁产生的必要条件:
四个条件同时满足。
①互斥条件:互斥资源的争抢;
②不剥夺条件:不会被其他进程强行夺走,只能主动释放;
③请求和保持条件: 已有一个资源,请求新的资源,但新资源被其他进程占有;请求进程被阻塞;
④循环等待条件:存在进程资源循环等待链;链中每个进程都已获得资源,同时被下一个进程所请求。
(2)死锁的处理策略:
①预防死锁。破环任意一个必要条件。
②避免死锁。例如tryclock加锁时,不成功时就会返回。
③死锁的检测和解除。