3线程同步:条件变量

简介: 1条件变量 条件变量给多个线程提供了一个汇合的场所。 依赖的头文件 #include<pthread.h> 函数声明 定义分配条件变量 pthread_cond_t cond =PTHREAD_COND_INITIALIZER;   int pthread_cond_init(pthread_cond_t*restrict c

1条件变量

条件变量给多个线程提供了一个汇合的场所。

依赖的头文件

#include<pthread.h>

函数声明

定义分配条件变量

pthread_cond_t cond =PTHREAD_COND_INITIALIZER;

 

int pthread_cond_init(pthread_cond_t*restrict cond, const pthread_condattr_t *restrict attr);

名称:

pthread_cond_init

功能:

initialize condition variables  初始化条件变量

头文件:

#include <pthread.h>

函数原形:

int pthread_cond_init(pthread_cond_t *restrict cond,

             const pthread_condattr_t *restrict attr);

参数:

 

返回值:

the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error

 

int pthread_cond_destroy(pthread_cond_t*cond);

名称:

pthread_cond_destroy

功能:

Destroy condition variables  销毁条件变量

头文件:

#include <pthread.h>

函数原形:

int pthread_cond_destroy(pthread_cond_t *cond);

参数:

 

函数说明:

在释放或废弃条件变量之前,需要毁坏它,使用此函数

返回值:

the pthread_cond_destroy() and pthread_cond_init() functions shall return zero; otherwise, an error number shall be returned to indicate the error

 

int pthread_cond_wait(pthread_cond_t*restrict cond,pthread_mutex_t *restrict mutex);

名称:

pthread_cond_wait

功能:

Wait on a condition,等待某个条件是否成立。对于timewait()函数除了等待以外,可以设置一个时长。

头文件:

#include <pthread.h>

函数原形:

intpthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

参数:

 

函数说明:

一旦初始化了互斥对象和条件变量,就可以等待这个条件,一个特定条件只能有一个互斥对象,而且条件变量应该表示互斥数据“内部”的一种特殊的条件更改。一个互斥条件可以用许多条件变量(例如:cond_empty,cond_full,cond_cleanup,但每个条件变量只能有一个互斥对象。

返回值:

 

 

int pthread_cond_signal(pthread_cond_t*cond);

名称:

pthread_cond_signal

功能:

signal a condition,这种情况是只有一个线程收到后执行动作。

头文件:

#include <pthread.h>

函数原形:

int pthread_cond_signal(pthread_cond_t *cond);

参数:

 

函数说明:

活动线程只需要唤醒第一个正在睡眠的线程。假设您只对队列添加了一个工作作业。那么只需要唤醒一个工作程序线程(再唤醒其它线程是不礼貌的!)

返回值:

 

 

int pthread_cond_broadcast(pthread_cond_t*cond);

名称:

pthread_cond_broadcast

功能:

broadcast a condition,通过广播的形式发给子线程消息,子线程竞争执行。

头文件:

#include <pthread.h>

函数原形:

int pthread_cond_broadcast(pthread_cond_t *cond);

参数:

 

函数说明:

如果线程更改某些共享数据,而且它想要唤醒所有正在等待的线程,则应使用 pthread_cond_broadcast调用

返回值:

 

案例说明:

#include <stdlib.h>

#include <pthread.h>

#include <stdio.h>

#include <unistd.h>

 

struct msg {

   struct msg *next;

   int num;

};

 

struct msg *head;

/*条件变量 */

pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void *consumer(void *p)

{

   struct msg *mp;

   for (;;) {

       pthread_mutex_lock(&lock);

       /* pthread_cond_wait(&has_product, &lock);

        * 1.阻塞等待has_product被唤醒,

        * 2.释放互斥锁, pthread_mutex_unlock(&lock)

        * 3.当被唤醒时,解除阻塞,并且重新去申请获得互斥锁 pthread_mutex_lock(&lock)

        */

       while (head == NULL)

           pthread_cond_wait(&has_product, &lock);

 

       mp = head;

       head = mp->next;

       pthread_mutex_unlock(&lock);

       printf("Consume %d\n", mp->num);

       free(mp);

       sleep(rand() % 5);

   }

}

 

void *producer(void *p)

{

   struct msg *mp;

   for (;;) {

       mp = (struct msg *)malloc(sizeof(struct msg));

       mp->num = rand() % 1000 + 1;

       printf("Produce %d\n", mp->num);

       pthread_mutex_lock(&lock);

       mp->next = head;

       head = mp;

       pthread_mutex_unlock(&lock);

       /* pthread_cond_broadcast(&has_product)唤醒等待队列上的所有线程*/

                  //发送信号,告诉消费者有产品了

       pthread_cond_signal(&has_product);

       sleep(rand() % 5);

   }

}

 

int main(int argc, char *argv[])

{

   pthread_t pid, cid;

   srand(time(NULL));

   pthread_create(&pid, NULL, producer, NULL);

   pthread_create(&cid, NULL, consumer, NULL);

   pthread_join(pid, NULL);

   pthread_join(cid, NULL);

   return 0;

}

运行结果:

总结:从上面可以看出,消费者总是消费最先生产出来的一个。

目录
相关文章
|
存储 Java 测试技术
ThreadLocal:线程专属的变量
ThreadLocal:线程专属的变量
172 0
|
Java 开发者
解锁并发编程新姿势!深度揭秘AQS独占锁&ReentrantLock重入锁奥秘,Condition条件变量让你玩转线程协作,秒变并发大神!
【8月更文挑战第4天】AQS是Java并发编程的核心框架,为锁和同步器提供基础结构。ReentrantLock基于AQS实现可重入互斥锁,比`synchronized`更灵活,支持可中断锁获取及超时控制。通过维护计数器实现锁的重入性。Condition接口允许ReentrantLock创建多个条件变量,支持细粒度线程协作,超越了传统`wait`/`notify`机制,助力开发者构建高效可靠的并发应用。
220 0
|
12月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
210 6
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
|
安全 Linux
Linux线程(十一)线程互斥锁-条件变量详解
Linux线程(十一)线程互斥锁-条件变量详解
|
存储 SQL Java
(七)全面剖析Java并发编程之线程变量副本ThreadLocal原理分析
在之前的文章:彻底理解Java并发编程之Synchronized关键字实现原理剖析中我们曾初次谈到线程安全问题引发的"三要素":多线程、共享资源/临界资源、非原子性操作,简而言之:在同一时刻,多条线程同时对临界资源进行非原子性操作则有可能产生线程安全问题。
279 1
|
存储 Python 容器
Node中的AsyncLocalStorage 使用问题之在Python中,线程内变量的问题如何解决
Node中的AsyncLocalStorage 使用问题之在Python中,线程内变量的问题如何解决
|
调度
线程操作:锁、条件变量的使用
线程操作:锁、条件变量的使用
97 1
|
存储 缓存 算法
同时使用线程本地变量以及对象缓存的问题
【7月更文挑战第15天】同时使用线程本地变量和对象缓存需小心处理以避免数据不一致、竞争条件及内存泄漏等问题。线程本地变量使各线程拥有独立存储,但若与对象缓存关联,可能导致多线程环境下访问旧数据。缺乏同步机制时,多线程并发修改缓存中的共享对象还会引起数据混乱。此外,若线程结束时未释放对象引用,可能导致内存泄漏。例如,在Web服务器场景下,若一更新缓存而另一线程仍获取旧数据,则可能返回错误信息;在图像处理应用中,若多线程无序修改算法对象则可能产生错误处理结果。因此,需确保数据一致性、避免竞争条件并妥善管理内存。
125 0

热门文章

最新文章