多线程(2)-线程同步条件变量

news/发布时间2024/5/16 20:13:35
在 Linux 多线程编程中,条件变量是一种用于线程间同步的重要机制。它通常与互斥锁结合使用,用于解决多个线程竞争共享资源的问题。条件变量允许一个线程在等待某个条件变为真时阻塞,并且在另一个线程改变条件并通知时恢复执行。这个玩意跟内核等待队列差不多意思。
 
在 Linux 多线程编程中,使用条件变量进行线程同步通常涉及以下几个相关的函数:
pthread_cond_init: 该函数用于初始化条件变量。
原型为 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)。
参数 cond 是要初始化的条件变量,attr 是条件变量的属性,通常为 NULL。pthread_cond_destroy: 用于销毁条件变量。
原型为 int pthread_cond_destroy(pthread_cond_t *cond)。
参数 cond 是要销毁的条件变量。pthread_cond_wait: 该函数用于等待条件变量的状态发生变化。
原型为 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)。
参数 cond 是要等待的条件变量,mutex 是与条件变量配合使用的互斥锁。在调用该函数时,线程会释放互斥锁并阻塞,直到条件变量被其他线程发出信号唤醒。pthread_cond_timedwait: 类似于 pthread_cond_wait,但是可以设置超时时间,防止永久等待。
原型为 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)。pthread_cond_signal: 该函数用于发送信号给等待条件变量的一个线程。
原型为 int pthread_cond_signal(pthread_cond_t *cond)。调用该函数会唤醒等待队列中的一个线程。pthread_cond_broadcast: 类似于 pthread_cond_signal,但会唤醒等待队列中的所有线程。
原型为 int pthread_cond_broadcast(pthread_cond_t *cond)。
 

条件变量demo:

在此demo中,有一个生产者线程和一个消费者线程,它们共享一个整数变量 shared_data。生产者线程周期性地增加 shared_data 的值,而消费者线程在 shared_data 不为零时消费一个数据。生产者在生产了一个数据后会发送信号通知消费者线程,消费者在消费数据时需要先检查条件是否满足,如果不满足,则等待条件变为真。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int shared_data = 0;void* producer(void* arg) {while (1) {pthread_mutex_lock(&mutex);shared_data++; // 生产一个数据printf("Produced: %d\n", shared_data);pthread_cond_signal(&cond); // 发送信号通知消费者pthread_mutex_unlock(&mutex);sleep(1); // 生产者休眠1秒
    }return NULL;
}void* consumer(void* arg) {while (1) {pthread_mutex_lock(&mutex);while (shared_data == 0) { // 等待条件变为真pthread_cond_wait(&cond, &mutex);}printf("Consumed: %d\n", shared_data);shared_data--; // 消费一个数据pthread_mutex_unlock(&mutex);}return NULL;
}int main() {pthread_t producer_thread, consumer_thread;pthread_create(&producer_thread, NULL, producer, NULL);pthread_create(&consumer_thread, NULL, consumer, NULL);pthread_join(producer_thread, NULL);pthread_join(consumer_thread, NULL);return 0;
}
 

条件变量demo执行结果:

0
 
 
 
 
 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/45455661.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

进程间通信(4)-信号量

Linux 中的信号量通常指的是进程间通信(IPC)中的一种机制,用于实现进程之间的同步和互斥。在 Linux 中,主要有两种类型的信号量:System V 信号量和 POSIX 信号量。 1. System V 信号量 System V 信号量是最早引入 Linux 的一种进程间通信机制,它使用 semget、semctl 和 s…

进程间通信(2)-消息队列

Linux 中的消息队列是一种进程间通信(IPC)机制,允许不同进程之间通过消息进行通信。消息队列中的相关函数:msgget:创建或打开一个消息队列。 函数原型:int msgget(key_t key, int msgflg); 参数: key:消息队列的键值,用于标识消息队列。 msgflg:标志参数,用于指定消…

进程间通信(1)-管道

匿名管道(Anonymous Pipe)和有名管道(Named Pipe,也称为FIFO)是两种不同的进程间通信方式,它们有以下主要区别:命名和使用方式:匿名管道没有名字,只能在具有亲缘关系的进程之间使用,通常是在调用pipe()函数后直接使用,无需其他步骤。 有名管道有一个文件名,它在文件…

异常编译代码分析

异常编译代码分析 https://lowlevelbits.org/compiling-ruby-part-5/ 调用堆栈、堆栈帧和程序计数器 在程序执行期间,机器维护指向正在执行的指令的指针。它被称为程序计数器(或指令指针)。 当调用一个方法时,程序计数器被设置为被调用函数(被调用者)上的第一条指令。一旦…

Flask 框架启动无法改变端口

避坑! 相信大家使用flask框架的时候有时候会出现无法修改启动端口的情况. 在这里一共有两种解决办法(目前发现)1- 如果你使用的是flask Server 方式启动的你的项目的话, 可以Pycharm的环境变量中指定:FLASK_RUN_PORT=[PORT]2- 如果你使用的Python的话, 可以在代码中手动修改端口…

Java软件安装以及环境配置

Java软件安装以及环境配置 一、JDK安装 JDK官网:https://www.oracle.com/java/technologies/downloads/#java8 根据自己的电脑配置,安装对应平台,对应操作系统的JDK。 本人下载的是Windows x64版本的JDK。