Linux 条件变量

一、什么是条件变量

与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。

条件变量使我们可以睡眠等待某种条件出现。条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。

条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步。

使用条件变量之前要先进行初始化。可以在单个语句中生成和初始化一个条件变量如:

pthread_cond_t my_condition=PTHREAD_COND_INITIALIZER;(用于进程间线程的通信)。

也可以利用函数pthread_cond_init动态初始化。

二、条件变量函数


名称:


pthread_cond_init


目标:


条件变量初始化


头文件:


#include < pthread.h>


函数原形:


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


参数:


cond  条件变量

attr  条件变量属性


返回值:


成功返回0,出错返回错误编号。

pthread_cond_init函数可以用来初始化一个条件变量。他使用变量attr所指定的属性来初始化一个条件变量,如果参数attr为空,那么它将使用缺省的属性来设置所指定的条件变量。


名称:


pthread_cond_destroy


目标:


条件变量摧毁


头文件:


#include < pthread.h>


函数原形:


int pthread_cond_destroy(pthread_cond_t *cond);


参数:


cond  条件变量

pthread_cond_destroy函数可以用来摧毁所指定的条件变量,同时将会释放所给它分配的资源。调用该函数的进程也并不要求等待在参数所指定的条件变量上。


名称:


pthread_cond_wait/pthread_cond_timedwait


目标:


条件变量等待


头文件:


#include < pthread.h>


函数原形:


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

int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t mytex,const struct timespec *abstime);


参数:


cond 条件变量

mutex 互斥锁


返回值:


成功返回0,出错返回错误编号。

第一个参数*cond是指向一个条件变量的指针。第二个参数*mutex则是对相关的互斥锁的指针。函数pthread_cond_timedwait函数类型与函数pthread_cond_wait,区别在于,如果达到或是超过所引用的参数*abstime,它将结束并返回错误ETIME.pthread_cond_timedwait函数的参数*abstime指向一个timespec结构。该结构如下:

typedef struct timespec{

time_t tv_sec;

long tv_nsex;

}timespec_t;


名称:


pthread_cond_signal/pthread_cond_broadcast


目标:


条件变量通知


头文件:


#include < pthread.h>


函数原形:


int pthread_cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);


参数:


cond 条件变量


返回值:


成功返回0,出错返回错误编号。

参数*cond是对类型为pthread_cond_t
的一个条件变量的指针。当调用pthread_cond_signal时一个在相同条件变量上阻塞的线程将被解锁。如果同时有多个线程阻塞,则由调度策略确定接收通知的线程。如果调用pthread_cond_broadcast,则将通知阻塞在这个条件变量上的所有线程。一旦被唤醒,线程仍然会要求互斥锁。如果当前没有线程等待通知,则上面两种调用实际上成为一个空操作。如果参数*cond指向非法地址,则返回值EINVAL。

#include <pthread.h>

#include <stdio.h>
#include <stdlib.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;/*初始化互斥锁*/
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;/*初始化条件变量*/

void *thread1(void *);
void *thread2(void *);

int i=1;
int main(void)
{
    pthread_t t_a;
    pthread_t t_b;

pthread_create(&t_a,NULL,thread1,(void *)NULL);/*创建进程t_a*/
    pthread_create(&t_b,NULL,thread2,(void *)NULL); /*创建进程t_b*/
    pthread_join(t_b, NULL);/*等待进程t_b结束*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);
    exit(0);
}

void *thread1(void *junk)
{
    for(i=1;i<=9;i++) 
    {
      pthread_mutex_lock(&mutex);/*锁住互斥量*/
       if(i%3==0)
       pthread_cond_signal(&cond);/*条件改变,发送信号,通知t_b进程*/
       else 
       printf("thead1:%d\n",i);
       pthread_mutex_unlock(&mutex);/*解锁互斥量*/
sleep(1);
}
}

void *thread2(void *junk)
{
    while(i<9)
    {
      pthread_mutex_lock(&mutex);
if(i%3!=0)
         pthread_cond_wait(&cond,&mutex);/*等待*/
      printf("thread2:%d\n",i);
      pthread_mutex_unlock(&mutex);
sleep(1);
}
}

程序创建了2个新线程使他们同步运行,实现进程t_b打印10以内3的倍数,t_a打印其他的数,程序开始线程t_b不满足条件等待,线程t_a运行使a循环加1并打印。直到i为3的倍数时,线程t_a发送信号通知进程t_b,这时t_b满足条件,打印i值。

下面是运行结果:

#gcc –-lpthread –-o cond cond.c

#./cond

thread1:1

thread1:2

thread2:3

thread1:4

thread1:5

thread2:6

thread1:7

thread1:8

thread2:9

时间: 2024-12-21 13:39:06

Linux 条件变量的相关文章

理解 Linux 条件变量

理解 Linux 条件变量 1 简介 当多个线程之间因为存在某种依赖关系,导致只有当某个条件存在时,才可以执行某个线程,此时条件变量(pthread_cond_t)可以派上用场.比如: 例1: 当系统不忙(这是一个条件)时,执行扫描文件状态的线程. 例2: 多个线程组成线程池,只有当任务队列中存在任务时,才用其中一个线程去执行这个任务.为避免惊群(thrundering herd),可以采用条件变量同步线程池中的线程. 2 用法 条件变量(pthread_cond_t)必须与锁(pthread_

linux条件变量使用和与信号量的区别

近来在项目中用到条件变量和信号量做同步时,这一块一直都有了解,但也一直没有总结,这次总结一下,给大家提供点参考,也给自己留点纪念. 首先,关于信号量和条件变量的概念可以自行查看APUE,我这直接把APUE中的代码拿过来对比: 条件变量的使用: #include <pthread.h> struct msg { struct msg *m_next; /* ... more stuff here ... */ }; struct msg *workq; pthread_cond_t qready

Linux 条件变量函数signal和wait补充

pthread_cond_wait必须放在pthread_mutex_lock和pthread_mutex_unlock之间,因为他要根据共享变量的状态来觉得是否要等待,而为了不永远等待下去所以必须要在lock/unlock中共享变量的状态改变必须遵守lock/unlock的规则 pthread_cond_signal即可以放在pthread_mutex_lock和pthread_mutex_unlock之间,也可以放在pthread_mutex_lock和pthread_mutex_unloc

linux多线程-互斥&amp;条件变量与同步

多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int g_val = 10; void * test1(void* args) { g_val = 20; printf(&

Linux 线程 条件变量

下面是一个多线程,生产者消费者问题,一个队列放暂存的数据: 1 #include <iostream> 2 #include <queue> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <pthread.h> 6 7 using std::cout; 8 using std::endl; 9 using std::queue; 10 11 #define N 100 12 #def

Linux互斥量&amp;条件变量

互斥量 Mutex 互斥量1. #include <pthread.h>  2. int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);  3.   4. int pthread_mutex_lock(pthread_mutex_t *mutex);  5.   6. int pthread_mutex_unlock(pthread_mutex_t *mutex);  7.   

Linux多线程编程-条件变量

条件变量 如果说线程间的互斥锁是用来同步共享数据的访问的话,那么条件变量是用于线程之间共享数据的值.条件变量提供了一种线程之间的通知机制,当某个共享数据达到某个值时,唤醒等待这个共享数据的线程.条件变量相关函数主要 有5个: #include <pthread.h> int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *cond_attr); int pthread_cond_destroy(pthread_

Linux多线程编程的条件变量

在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平好高的.这里把他的回答粘贴一下方便以后查看,原帖在这里:When is a conditional variable needed, isn't a mutex enough? Even though you can use them in the way you describe, mutexes

转载~kxcfzyk:Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解

Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解 多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁,但是对条件变量完全不知道或者不完全了解的人群.如果您对这些都没什么概念,可能需要先了解一些基础知识) 关于条件变量典型的实际应用,可以参考非常精简的Linux线程池实现(一)——使用互斥锁和条件变量,但如果对条件变量不熟悉最好先看完本文. Pthread库的条件变量机制的主要API有三个: int p