博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程同步
阅读量:6218 次
发布时间:2019-06-21

本文共 2752 字,大约阅读时间需要 9 分钟。

线程同步

  • 互斥锁mutex
 

锁类型

初始化方式

加解锁特征

调度特征

普通锁

PTHREAD_MUTEX_TIMED_NP

PTHREAD_MUTEX_INITIALIZER

同一线程可重复加锁,解锁一次释放锁

先等待锁的进程先获得锁

嵌套锁

PTHREAD_MUTEX_RECURSIVE_NP

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP

同一线程可重复加锁,解锁同样次数才可释放锁

先等待锁的进程先获得锁

纠错锁

PTHREAD_MUTEX_ERRORCHECK_NP

PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP

同一线程不能重复加锁,加上的锁只能由本线程解锁

先等待锁的进程先获得锁

自适应锁

PTHREAD_MUTEX_ADAPTIVE_NP

PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP

同一线程可重加锁,解锁一次生效

所有等待锁的线程自由竞争

 
#include 
int pthread_mutex_destroy(pthread_mutex_t *mutex);int pthread_mutex_init(pthread_mutex_t *restrict mutex, pthread_mutexattr_t *restrict attr);pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

如果mutex变量是静态分配的(全局变量或static变量),也可以用宏定义PTHREAD_MUTEX_INITIALIZER来初始化,相当与用pthread_mutex_init()初始化并且设置attr为NULL。

int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);

trylock失败,返回EBUSY。

#include 
#include
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime);

超时指定愿意等待的绝对时间(与相对时间对比而言,指定在时间X之前可以阻塞等待,而不是说愿意阻塞Y秒)。这个超时时间是用timespec结构来表示,它用秒和纳秒来描述时间。

为了实现互斥操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性。即使是多处理器平台,访问内存的总线周期也有先后,一个处理器上的交换指令执行时,另外一个处理器的交换指令只能等待总线周期。

pthread_mutex_lock(&m);    while(a <= 0)        TODO    pthread_mutex_unlock(&m);

while多执行一次,检测a是否大于0。多线程执行时,一线程响应后a=0;其余线程执行a<=0时阻塞。

上述code在一直执行如下操作:获取锁----条件不满足----释放锁----获取锁----条件不满足----释放锁......,因此引入条件变量。

  • 条件变量condition variable

线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。

在pthread库中通过条件变量( Condition Variable) 来阻塞等待一个条件,或者唤醒等待这个条件的线程。 Condition Variable用pthread_cond_t类型的变量表示。

#include
int pthread_cond_destory(pthread_cond_t *cond);int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);int pthread_cond_broadcast(pthread_cond_t *cond);//唤醒所有线程int pthread_cond_signal(pthread_cond_t *cond); //唤醒一个线程

一个条件变量总是和一个mutex搭配使用。

pthread_cond_wait()在一个condtion variable上阻塞等待,这个函数做以下三步:

  1. 释放mutex;
  2. 阻塞等待; 1,2合成原子操作。
  3. 当被唤醒时,重新获得mutex并返回(原子性的)。
pthread_mutex_lock(&m);    while(a <= 0)        TODO    pthread_mutex_unlock(&m);

while多执行一次,检测a是否大于0。多线程执行时,一线程响应后a=0;其余线程执行a<=0时阻塞。

上述code在一直执行如下操作:获取锁----条件不满足----释放锁----获取锁----条件不满足----释放锁......,可引入条件变量。

pthread_mutex_lock(&m);    while(a <= 0)        pthread_cond_wait(&c, &m);    pthread_mutex_unlock(&m);

 


  • 信号量semaphore

见信号量博文。

  • 其他线程见同步机制 只要有一个线程可以改写数据,就必须考虑线程见同步问题,引入了读者写者锁(Reader-Writer Lock)。

转载地址:http://ywlja.baihongyu.com/

你可能感兴趣的文章
VS2017 15.4提供预览版,面向Windows 10秋季更新(FCU)
查看>>
如何通俗易懂地向别人解释React生命周期方法?
查看>>
马化腾:电力时代孕育了计算机,人工智能兴盛于云计算
查看>>
esp8266代码中的存储标记
查看>>
如何在C++中使用空引用及该或不该
查看>>
进击JavaScript之(三)玩转闭包
查看>>
js面试
查看>>
AngularJS指令实践
查看>>
Python工具分析风险数据
查看>>
Git自由之章 - 关于SSH 公钥
查看>>
关于classpath中有多个同名类或一个接口有多个实现类Spring启动失败总结
查看>>
数组reduce方法的高级技巧
查看>>
pt-online-schema-change使用说明、限制与比较
查看>>
一些小技巧让JS代码更优雅
查看>>
jquery 添加和删除html元素
查看>>
Java 8怎么了之二:函数和原语
查看>>
dingo/api 使用
查看>>
PHP字符串函数之 strstr stristr strchr strrchr
查看>>
mac安装docker
查看>>
Objective-C runtime 拾遗 (二)——Log message send
查看>>