线程同步

线程同步:线程之间协同工作,用于多线程访问临界资源,必须按照一定的先后顺序访问执行。

一. 线程级信号量

线程的信号量与进程间通信中使用的信号量的概念是一样,它是一种特殊的变量,它可以被增加或减少,但对其的关键访问被保证是原子操作。如果一个程序中有多个线程试图改变一个信号量的值,系统将保证所有的操作都将依次进行。

二进制信号量——0,1
计数信号量——更大范围的信号量
1、创建信号量

#include <semaphore.h>
sem_t sem;//信号量类型

int sem_init(sem_t sem,int shared,int flag);
//函数初始化有sem指向的信号量对象;
//shared 信号量是否可以在进程间共享,Linux不支持,一般为0;
//flag 设置信号量的初始值

调用成功时返回0,失败返回-1.

2、sem_wait函数用于以原子操作的方式将信号量的值减1。原子操作就是,如果两个线程企图同时给一个信号量加1或减1,它们之间不会互相干扰。它的原型如下:

int sem_wait(sem_t *sem);
//p操作    sem指向的对象是由sem_init调用初始化的信号量

调用成功时返回0,失败返回-1.

3、sem_post该函数用于以原子操作的方式将信号量的值加1。

int sem_post(sem_t *sem);
//v操作   sem指向的对象是由sem_init调用初始化的信号量

调用成功时返回0,失败返回-1.

4、sem_destroy该函数用于对用完的信号量的清理。

int sem_destroy(sem_t *sem);
//销毁信号量

调用成功时返回0,失败返回-1.

二. 互斥锁——>针对一个临界资源加锁或者解锁

pthread_mutex_t//定义一个锁

int pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutexattr_t *attr);
//初始化锁

//加锁
int pthread_mutex_lock(pthread_mutex_t *mutex);//阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);//不会阻塞

//解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);

//销毁
int pthread_mutex_detroy(pthread_mutex_t *mutex);

三. 读写锁

读写锁与互斥量类似,但是读写锁允许更高的并行性。
互斥量要么是锁住状态要么是不加锁状态,而且一次只有一个线程可以对其加锁;
读写锁可以有三种状态:读模式下加锁状态、写模式下加锁状态、不加锁状态。注意:一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。

四. 自旋锁

自旋锁和互斥量类似,区别是:若线程不能获取锁,互斥量是通过休眠的方式(线程被暂时取消调度,切换至其他可运行的线程)来阻塞线程;而自旋锁则是通过忙等待的方式(线程不会被取消调度,一直在处于运行状态)来阻塞线程。

自旋锁适用于:锁被其他线程短期持有(很快会被释放),而且等待该锁的线程不希望在阻塞期间被取消调度,因为这会带来一些开销。

五. 条件变量

条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待“条件变量的条件成立”挂起;另一个线程使“条件成立”。
条件本身是由互斥量保护的,线程在改变条件状态前先要锁住互斥量,它利用线程间共享的全局变量进行同步控制的一种机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值