Linux线程唤醒与等待
生产者消费者模式在程序设计中出现频率非常高,经常会有线程间通过消息队列或其他共享变量进行交互的场景。而这时就会出现一个问题,消费者如何知道生产者已经生产了数据呢?有的程序会采取消费者循环判断消息队列大小是否为0,如果不为0则取出数据之类的方法。但是该种方法带来两个问题:
1. 生产者产出数据到消费者获得数据的延时较大。
2. CPU占用较高。
如果需要降低延时,则必然要提高轮询的频率,那么CPU占用就会升高。反之亦然,两者无法同时解决。
于是,唤醒等待机制就成为适合该种场景的解决方案。
该机制需要一个互斥对象以及条件变量共同完成,如下:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex;
其中条件变量使用宏结构常量进行赋值。接下来进行互斥对象与条件变量的初始化:
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
生产者唤醒逻辑:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
消费者等待逻辑:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
看到这里可能会有点疑问,为何除了条件变量还需要一个互斥对象呢?等待时为什么需要条件变量和互斥对象共同生效呢?
条件变量的操作也需要达到线程安全的要求,因此需要互斥对象来进行保证。避免两个线程同时操作条件变量引发问题。而通过查阅pthread_cond_wait()的相关资料可知,当程序运行到pthread_cond_wait()时,会将互斥对象锁释放,以便生产者能够顺利唤醒。而在消费者被成功唤醒,pthread_cond_wait()等待完成后,互斥对象会被重新上锁直到手动释放。
下方提供完整的DEMO以供参考:
/* test.cpp */ #include <pthread.h>
#include <iostream>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h> using namespace std; pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex; void *ThreadFunc(void *arg) { pthread_mutex_lock(&mutex);
/*此处等待唤醒*/
cout << "Thread sleeping..." << endl;
pthread_cond_wait(&cond, &mutex);
/*唤醒成功*/
cout << "Thread awakened!" << endl;
pthread_mutex_unlock(&mutex); return NULL;
} int main(void) { pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL); pthread_t tid;
pthread_create(&tid, NULL, ThreadFunc, NULL); /*等待5秒再唤醒,方便观察*/
usleep(); pthread_mutex_lock(&mutex);
/*唤醒*/
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex); return ;
}
附上操作命令:
g++ test.cpp -o test -pthread
./test
Linux线程唤醒与等待的更多相关文章
- Java多线程02(线程安全、线程同步、等待唤醒机制)
Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...
- “全栈2019”Java多线程第三十四章:超时自动唤醒被等待的线程
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- 第十七节:Runnable创建线程,Thread创建线程,唤醒线程和计数器多线程,线程同步与等待
Runnable创建线程 public class RunnableDemo implements Runnable{ @Override public void run(){ int i = 1; ...
- Linux 线程管理
解析1 LINUX环境下多线程编程肯定会遇到需要条件变量的情况,此时必然要使用pthread_cond_wait()函数.但这个函数的执行过程比较难于理解. pthread_cond_wait()的工 ...
- linux线程
线程:轻量级进程,在资源.数据方面不需要进行复制 不间断地跟踪指令执行的路径被称为执行路线 进程的结构:task_struck:地址空间 线程:轻量级的进程 在同一个进程中创建的线程,在共享进程的地址 ...
- Linux线程学习(一)
一.Linux进程与线程概述 进程与线程 为什么对于大多数合作性任务,多线程比多个独立的进程更优越呢?这是因为,线程共享相同的内存空间.不同的线程可以存取内存中的同一个变量.所以,程序中的所有线程都可 ...
- Linux 线程与进程,以及通信
http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...
- 【转】 Linux 线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...
- (转)linux进程 linux线程 信息查看 ps top pstree
原文:https://blog.csdn.net/xiaoliuliu2050/article/details/81912202 https://blog.csdn.net/u011734144/ar ...
随机推荐
- node.js 初学 自我笔记整理 day01
node.js 概念问题: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. npm是一个node的包管理工具 ,也是一个网站 ,还是一条命令.N ...
- test-HTML
吃葡萄不吐葡萄皮- Hello, This is my first html! baidu yiciyuan 防止嗅探 faststone capture picture movie ...
- c++ 按位或
|=是位操作运算符的一种,其形式为:a|=b代表的含义为a=a|b;即把a和b做按位或(|)操作,结果赋值给a.按位或的计算规则为:1 逐位进行计算:2 计算数的同位上值,如果均为0,则结果对应位上值 ...
- VMware网络设置的三种方式
VMWare提供了三种工作模式:host-only(主机模式).NAT(网络地址转换模式).bridged(桥接模式) 1.host-only(主机模式) 在某些特殊的网络调试环境中,如何要求将真实环 ...
- 虚拟机中安装Oracle 12c
1.从本地电脑中拉oracle到Linux 2.安装Linux中的oracle 12C 拉oracle到Linux 1.点击"编辑虚拟机设置" 2.点击"硬盘" ...
- svn checkout 单个文件
$ svn co --depth=empty file:///usr/local/svn/calc calc_new $ cd calc_new $ svn up readme.txt 其中,calc ...
- c# timestamp转换datetime
一.Codes class Program { static void Main(string[] args) { ); } public static DateTime UnixTimeStampT ...
- (数据科学学习手札67)使用Git管理Github仓库
一.简介 Git是目前使用最广泛的分布式版本控制系统,通过Git可以方便高效地管理掌握工作过程中项目内容文件的更新变化情况,通过Git我们可以以命令行的形式完成对Github上开源仓库的clone,以 ...
- Unity进阶:PlayMaker
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
- 福建工程学院16级第一周寒假作业E题----第七集,奇思妙想
第七集,奇思妙想 ...