day27 同步互斥

发布于:2025-08-09 ⋅ 阅读:(17) ⋅ 点赞:(0)

同步互斥

线程资源是共享的,此时会出现多个线程对全局变量的访问,导致数据错误,以此引入同步互斥

临界资源:多个线程抢夺的资源(全局变量,文件,数据库,内核资源)

临界区:访问临界资源的代码

互斥:同一时间内只允许一个线程访问临界资源(共享资源)

同步:在互斥的基础上保证访问者的顺序

解决同步互斥问题:互斥锁,信号量,条件变量

互斥锁

概念

对于要访问临界资源的线程做上锁操作,如果上锁成功,则访问成功,如果上锁失败,则阻塞并等待互斥锁解锁再解除阻塞,再执行

速记

函数 功能 参数 返回值
pthread_mutex_init 初始化 &mutex,        NULL 永0
pthread_mutex_lock 上锁 &mutex  成功0,失败非0
pthread_mutex_unlock 解锁 &mutex  成功0,失败非0
pthread_mutext_destroy 销毁锁 &mutex  成功0,失败非0
pthread_mutex_trylock 尝试上锁 &mutex  成功0,失败非0

相关函数

pthread_mutex_init

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

功能:初始化进程锁

定义方式:推荐第二个,我懒  ,可定义为全局

                   1.int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

                   2.pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;

参数:pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

           const pthread_mutexattr_t *mutexattr       互斥锁属性 快速(默认),递归,错误检错锁

                                                                              默认NULL

返回值:永为0 

pthread_mutex_lock

int pthread_mutex_lock(pthread_mutex_t *mutex);

功能:上锁,如果锁资源被占用,阻塞等待,直到锁资源被释放解除阻塞上锁成功

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutex_unlock

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁,释放锁资源

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutext_destroy

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:销毁锁资源

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

pthread_mutex_trylock

int pthread_mutex_trylock(pthread_mutex_t *mutex);

功能:尝试上锁,锁资源被占用了不会阻塞,报错EBUSY

参数: pthread_mutex_t *mutex        指向内存中mutex锁的地址的指针

返回值:成功返回0,失败返回非0

死锁

1.重复上同一把锁

2.锁资源没有释放,线程异常退出

3.线程重复上多把锁

信号量

对于要访问临界资源的线程都做申请信号的操作

信号量大于0 申请成功,信号量-1  释放成功,信号量+1
等于0 申请失败,处于阻塞态,直到信号量大于0,解除阻塞

互斥锁:称为二值信号量(0,1)

解决问题:一个生产者少量消费者

P操作:申请  信号量-1

V操作:释放  信号量+1

速记

#include <semaphore.h>

函数 功能 参数 返回值
sem_init 初始化 &sem,0,value 成功返回0,失败返回-1,更新errno
sem_wait  申请P &sem 同上
sem_post 释放V &sem 同上
sem_destroy 销毁 &sem 同上
sem_getvalue 获取信号量 &sem,&sval 同上

Link with -pthread.

相关函数

sem_init

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:初始化的信号量

参数: sem_t *sem:该指针指向的内存中存储信号量

            int pshared: 0:表示线程共享 非0:表示进程共享

            unsigned int value:用于信号量的初始化,允许多少个线程同时访问临界资源

返回值: 成功返回0,失败返回-1,跟新errno

sem_wait 申请 P -1

int sem_wait(sem_t *sem);

功能:申请信号量 -1  大于0,成功,等于0阻塞,直到大于0解除

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_post 释放 V +1

int sem_post(sem_t *sem);

功能:释放信号量 +1 

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_destroy

int sem_destroy(sem_t *sem);

功能:销毁信号量

参数: sem_t *sem:该指针指向的内存中存储信号量

返回值: 成功返回-,失败返回-1,根新errno

sem_getvalue

int sem_getvalue(sem_t *sem, int *sval);

功能:获取信号量的值

参数: sem_t *sem:该指针指向的内存中存储信号量

            int *sval:         该指针指向的内存中存储信号量的值

返回值: 成功返回-,失败返回-1,根新errno

条件变量

对于不访问临界资源的线程休眠,并设置一个唤醒条件(条件变量),如果该线程需要访问临界资源时,需要通过其他线程唤醒该线程

速记

函数 功能 参数 返回值
pthread_cond_init 初始化 &cond,NULL 0,非0
pthread_cond_wait 进程塞入等待队列 &cond,&mutex 同上
pthread_cond_siganl 唤醒队列第一个 &cond 同上
pthread_cond_broadcast 唤醒整个队列 &cond 同上
pthread_cond_destroy 销毁 &cond 同上

相关函数

pthread_cond_init

int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

功能:初始化条件变量

定义方式:推荐第二个,我懒  ,可定义为全局

                   1.int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

                   2.pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

参数:        pthread_cond_t *cond:该指针指向的内存中存储条件变量

                   pthread_condattr_t *cond_attr:条件变量属性

                                                                      NULL:默认属性

返回值:成功0,失败非0

pthread_cond_wait

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);

使用流程:

1.上锁pthread_muext_lock()

2.解锁,休眠 pthread_cond_wait()//解锁,休眠 ,上锁(如果被其他线程唤醒后 重新尝试上锁,如果上锁成功,则唤醒成功 如果上锁失败,则唤醒失败)

3.运行

4.解锁

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

            pthread_mutex_t *mutex:互斥锁

返回值:成功返回0,失败返回非0

-------------------------------------------

条件变量为什么使用互斥锁:

当多核CPU时,同一时间执行多个线程,且同时调用pthread_cond_wait函数,同时把多个线程存到 休眠队列中,此时这个休眠队列就是多个线程需要抢夺的临界资源,解决互斥问题,需要引入互斥锁 哪个县城抢夺到了互斥锁,就把哪个县城存到休眠队列中,存储以后解锁,其他线程在存储袋休眠队列即可

pthread_cond_siganl

int pthread_cond_signal(pthread_cond_t *cond);

功能:唤醒休眠队列的第一个线程

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0

pthread_cond_broadcast

int pthread_cond_broadcast(pthread_cond_t *cond);

功能:唤醒所有休眠队列的线程

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0

pthread_cond_destroy

int pthread_cond_destroy(pthread_cond_t *cond);

功能:销毁条件变量

参数: pthread_cond_t *cond:该指针指向的内存中存储条件变量

返回值:成功返回0,失败返回非0


网站公告

今日签到

点亮在社区的每一天
去签到