当前位置:首页 > 技术知识 > 正文内容

Linux系统编程:条件变量为什么要用锁

maynowei3周前 (08-03)技术知识14

条件变量可以解决线程同步和共享资源访问的问题,条件变量是对互斥锁的补充,它允许一个线程阻塞并等待另一个线程发送的信号,当收到信号时,阻塞的线程被唤醒并试图锁定与之相关的互斥锁。具体定义如下:

等待:

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 *abtime);

唤醒:

int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

具体使用场景:

在等待线程实现如下:

pthread_mutex_lock(&same_mutex);

pthread_cond_wait(&m_cond, &same_mutex);

pthread_mutex_unlock(&same_mutex);

在唤醒线程实现如下:

pthread_mutex_lock(&same_mutex);

pthread_cond_signal(&m_cond);

pthread_mutex_unlock(&same_mutex);

等待线程会在pthread_cond_wait()调用时挂起,并且在锁的保护下构造和检查好m_cond对应的条件链表后先解锁same_mutex,然后睡眠。这里解锁和睡眠是一个原子操作。当等待线程收到唤醒线程的通知后,pthread_cond_wait做的第一件事是把same_mutex重新加锁并唤醒返回,这里加锁和唤醒也是一个原子操作。

那么唤醒线程和等待线程为什么要用同一个mutex锁呢?首先,如果在等待线程调用了pthread_cond_wait()但是还没有开始等待(因为之前还要做链表的初始化工作),这时唤醒操作如果发生则会导致唤醒丢失(竞态条件)。因此必须使用锁防止条件链表这个共享资源被同时操作。(等待线程先在锁保护下操作完共享链表,然后解锁和睡眠是原子操作后开始睡眠,因此唤醒操作如果是在同一把锁保护中才能唤醒的话(唤醒也会修改共享链表),等待线程一定已经访问完共享资源并且睡眠了,就防止了冲突丢失唤醒信号)。 但是如果当前没有线程阻塞等待唤醒,pthread_cond_signal()函数调用后应没有任何效果。

因此条件变量使用锁是为了防止唤醒和等待操作同时发生的竞态条件,从而导致唤醒丢失甚至引起死锁。但是如果是认为不等待直接唤醒则该唤醒会直接丢失。

注:

最后pthread_cond_wait唤醒和加锁也是一个原子操作,如果有多个线程在同一个条件变量上等待,可以保证虽然都被唤醒了但是只有一个线程会获取到锁。

相关文章

苹果编程Objective C与Swift谁更牛?

小鹏大学刚刚毕业,软件开发方面的东西学的不是很多,听好多同学说做iOS开发工资上万是很容易的,踌躇满志,一直想自学iOS开发,可突如其来的一件事让他瞬间迷茫了。时间:2014年9月10日10点地点:某...

惊现!iOS 16.5 kfd 漏洞利用,成功隐藏 Dock 栏

最近!kfd漏洞比较活跃,进展也是很顺利,今天就有大神成功使用 kfd 漏洞实现隐藏 Dock 栏,到底怎么回事?请继续往下看。-- kfd 漏洞说明 --kfd漏洞适合在 iOS 16.2 - 16...

高考一词多义考点! 30个高频词汇,完形填空再也不怕啦

1. address·/a'dres/ v.处理(问题)We must address the issue of climate change.·/'aedres/ n.地址Pleas...

Android监听滚动视图(监听页面滚动)

Android UI Libs之Android-ObservableScrollView1. 说明Android-ObservableScrollView,顾名思义,Android上观察滚动的视图,可...

C# 中的多线程同步机制:lock、Monitor 和 Mutex 用法详解

在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。C# 提供了几种常用的同步机制,其中 lock、Monitor 和 Mutex 是最常用的同步工具。本文将全面介绍这三种同步机制的用...

从 async/await 到虚拟线程:Python 并发的再思考

演进之路:从async/await到线程的反思首先必须明确的是,async/await对Python并非全无裨益:它最大的价值,是让更多人接触到了并发编程。通过在编程语言中嵌入语法元素,并发编程的门槛...