目录
2.销毁线程属性-pthread_attr_destory()
3.设置线程属性-pthread_setdetachstate()
2.销毁互斥锁-pthread_mutex_destory()
3.使用pthread_mutex_trylock替代pthread_mutex_lock
一、线程的分离属性
1.1.什么是分离属性
线程在结束时由操作系统自动回收空间
1.2.分离属性相关函数接口
1.初始化线程属性-pthread_attr_init()
int pthread_attr_init(pthread_attr_t *attr);
功能:
初始化线程属性
2.销毁线程属性-pthread_attr_destory()
int pthread_attr_destroy(pthread_attr_t *attr);
功能:
销毁线程属性
3.设置线程属性-pthread_setdetachstate()
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
功能:
将线程设置为分离属性
参数:
attr:线程属性
detachstate:PTHREAD_CREATE_DETACHED 分离属性
PTHREAD_CREATE_JOINABLE 加入属性(默认)
1.3.注意
线程使用分离属性后,将不会让进程发生阻塞,从而不会实现进程与线程的同步;
默认的属性,需要pthread_join(),来回收线程空间,会实现同步;
二、互斥锁
2.1.资源
资源是有限的,在程序运行过程中,一段代码、一段空间、一个变量、CPU、内存都可以看做资源
2.2.互斥锁
1.什么是互斥锁
是一种资源,当一个线程任务加锁,其余线程任务无法再次加锁,直到解锁后才能加锁;
2.互斥锁的用途
互斥锁主要是用来防止多个线程任务竞争某个资源;
3.临界区
加锁和解锁中间的代码称为临界代码也称为临界区
2.3.函数接口
1.初始化互斥锁-pthread_mutex_init()
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
功能:
初始化互斥锁
参数:
mutex:互斥锁
attr:互斥锁属性 NULL
返回值:
成功返回0
失败返回-1
2.销毁互斥锁-pthread_mutex_destory()
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:
销毁互斥锁
参数:
mutex:互斥锁
返回值:
成功返回0
失败返回-1
3.枷锁-pthread_mutex_lock()
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:
加锁
参数:
mutex:互斥锁
返回值:
成功返回0
失败返回-1
4.解锁-pthread_mutex_unlock()
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:
解锁
参数:
mutex:互斥锁
返回值:
成功返回0
失败返回-1
2.4.注意点
1.互斥锁不能同步,多个任务依然保持异步执行,但是可以解决资源竞争
2.原子操作:最小的一次CPU操作,在执行原子操作时不会切换调度任务
三、死锁
3.1.什么是死锁
多线程加锁解锁导致多个任务均无法向下执行的状态称为死锁状态简称为死锁
3.2.产生死锁的4个必要条件
1.互斥条件
同一把锁不能被多个线程任务同时锁定
2.不剥夺条件
一个线程任务已经锁定了一个资源,不能被其他线程任务抢占,直到它使用完该资源
3.请求保持条件
如果没有拿到锁资源一直申请获得锁资源
4.循环等待条件
如果没有得到锁资源会一直等待
3.3.如何避免死锁
1.加锁顺序保持一致
2.打破互斥条件、不可剥夺条件(不建议使用)
3.使用pthread_mutex_trylock替代pthread_mutex_lock
pthread_mutex_trylock为尝试进行锁操作,若没有锁则不进行锁操作。
四、信号量
4.1信号量是什么
信号量是一种资源(可以初始化、销毁、申请、释放)
申请:资源数 > 0 申请操作让资源数-1
资源数 == 0 申请操作会阻塞,直到资源数不为0,申请得到资源后继续向下执行
释放:资源数+1
释放操作让资源数+1
4.2.信号量的作用
实现多线程间的同步(同步就是多个线程有一定的执行顺序)
4.3.函数接口
1.初始化信号量-sem_init()
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:
对信号量的初始化
参数:
sem:信号量空间首地址
pshared:
0 线程间共享
非0 进程间共享
value:信号量的初始值
返回值:
成功返回0
失败返回-1
2.销毁信号量-sem-destory()
int sem_destroy(sem_t *sem);
功能:
信号量的销毁
3.申请信号量-sem_wait()
int sem_wait(sem_t *sem);
功能:
申请信号量(资源数-1)
资源数为0阻塞等待直到有资源申请后继续向下执行
4.释放信号量-sem_post()
int sem_post(sem_t *sem);
功能:
释放信号量(资源数+1)
五、总结
2024年8月8日,学习的第25天。今天主要是学习了线程间的通信,其中引出了互斥锁、信号量和死锁的知识。总体来说,这块还是比较难的。
加油!