Linux 学习笔记
线程同步_互斥锁_读写锁_条件变量_信号量
1. 线程同步概念
同步 即协同步调,按预先的先后次序运行
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其他线程为保证数据一致性,不能调用该功能。
同步的目的,是为了避免数据混乱,解决与时间有关的错误。实际上,不仅线程间需要同步,进程间、信号间等等都需要同步机制
因此,所有”多个控制流,共同操作一个共享资源“的情况,都需要同步。
数据混乱的原因:
- 资源共享(独享资源则不会)
- 调度随机(意味着数据访问会出现竞争)
- 线程间缺乏必要的同步机制
2. 互斥量(互斥锁)
互斥量(互斥锁)mutex 建议锁(不具备强制性)
linux中提供一把互斥锁mutex
每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。
资源还是共享的,线程间也还是竞争的,但通过锁就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了
注意:同一时刻,只能有一个线程持有该锁
当A线程对某个全局变量加锁访问,B在访问前尝试加锁,拿不到锁,B阻塞。C线程不去加锁,而直接访问该全部变量,依然能够访问,但会出现数据混乱。
所以,互斥锁实质上是操作系统提供的一把”建议锁“(又称”协同锁“),建议程序中有多线程访问共享资源的时候使用该机制。但并没有强制限定
因此,即使有了mutex,如果有线程不按规则来访问数据,依然会造成数据混乱
2.1 demo 线程共享访问屏幕出现数据混乱
/* pthread_shared.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
void* tfn(void * arg)
{
srand(time(NULL));
while (1)
{
printf("hello ");
sleep(rand() % 3);
printf("world\n");
sleep(rand()% 3);
}
return NULL;
}
int main(int argc, char * argv [ ])
{
pthread_t tid;
srand(time(NULL));
pthread_create(&tid, NULL, tfn, NULL);
while(1)
{
printf("HELLO ");
sleep(rand()%3);
printf("WORLD\n");
sleep(rand()%3);
}
pthread_join(tid, NULL);
return 0;
}
2.2 mutex 相关函数
pthread_mutex_init 函数
pthread_mutex_destroy 函数
pthread_mutex_lock 函数
pthread_mutex_trylock 函数
pthread_mutex_unlock 函数
#include<pthread.h>
pthread_mutex_t mutex;
int pthread_mutex_init(pthread_mutex_t* restrict mutex, const pthread_mutexattr_t* restrict attr);
int pthread_mutex_destroy(pthread_mutex_t* mutex);
int pthread_mutex_lock(pthread_mutex_t* mutex);
int pthread_mutex_trylock(pthread_mutex_t* mutex);
int pthread_mutex_unlock(pthread_mutex_t* mutex);
restrict 关键字:
用来限定指针变量。被该关键字限定的指针变量所指向的内存操作,必须由本指针完成。
返回值:
成功:0
失败:-1
使用互斥锁的一般步骤:
- pthread_mutex_t lock; //创建锁
- pthread_mutex_init; //初始化
- pthread_mutex_lock; //加锁
- 访问共享数据
- pthread_mutex_unlock; //解锁
- pthread_mutex_destroy //销毁锁
demo 借助互斥锁管理共享数据实现同步
/* pthread_shared_mutex.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
pthread_mutex_t mutex;
void* tfn(void * arg)
{
srand(time(NULL));
while (1)
{
pthread_mutex_lock(&mutex); // 锁--