1.线程间通信
1.线程间通信方式
1.线程间可以通过使用全局变量来实现通信
2.多线程同时使用全局变量会引发资源竞争,要通过互斥锁来解决资源互争问题
2.概念
1.原子操作:不能被CPU任务调度打断的一次最小的操作称为原子操作
2.临界代码/临界区:加锁解锁中间的代码,这段代码用户不会被同时执行
3.互斥锁(相关API)
1.pthread_mutex_init
cs
int pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
功能:
初始化互斥锁
参数:
mutex:互斥锁空间首地址
attr:互斥锁的属性,默认属性NULL
返回值:
成功返回0
失败返回-1
2.pthread_mutex_destroy
cs
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:
互斥锁销毁
3.pthread_mutex_lock
cs
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:
互斥锁上锁
- pthread_mutex_unlock
cs
int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:
互斥锁解锁
4.死锁
1.由于多个锁的加锁解锁导致线程都无法继续执行的状态称为死锁
2.死锁产生的条件
互斥条件
不可剥夺条件
请求保持
循环等待
3.避免产生死锁
使用pthread_mutex_trylock替代pthread_mutex_lock
多把锁加锁顺序保持一致
5.信号量
-
信号量是这一种资源,在程序运行过程中,代码、变量、CPU、内存都可以看成是一种资源
-
资源一定是有限的,资源只能被初始化、销毁、申请和释放
3.相关API
1.sem_init
cs
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:
初始化信号量
参数:
sem:信号量的地址
pshared:
0:同一进程的线程间共享
非0:进程间共享
value:
初始化的值
返回值:
成功返回0
失败返回-1
2.sem_destory
cs
int sem_destroy(sem_t *sem);
功能:
销毁信号量
参数:
sem:信号量的首地址
返回值:
成功返回0
失败返回-1
3.sem_wait
cs
int sem_wait(sem_t *sem);
功能:
申请信号量,如果资源数>0则让资源数-1
如果资源数 == 0,阻塞等待直到资源 > 0 才能申请到资源继续向下
执行
参数:
sem:信号量空间首地址
返回值:
成功返回0
失败返回-1
4.sem_post
cs
int sem_post(sem_t *sem);
功能:
释放资源,让资源数+1
参数:
sem:信号量空间首地址
返回值:
成功返回0
失败返回-1
6.快速判断何时用互斥或信号
1.只是保护一块共享数据,防止多线程同时修改用互斥锁
2.需要A线程等待B线程完成某件事,做执行顺序控制用信号