Linux c 条件变量cond的使用记录

  条件变量是实现线程间同步的一种方法,条件变量用来自动阻塞一个线程,直到收到收到一个cond信号或其它特殊情况发送,条件变量使用的时候必须与互斥量同时使用,这是为了保证条件量在线程间操作的“原子性”。

1、创建一个条件变量cond:

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

在初始化一个条件变量时如果attr为 NULL,测使用默认值初始化一个条件变量cond,相当于下面的方式定义一个条件变量cond;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

2、销毁一个条件变量cond:

int pthread_cond_destroy(pthread_cond_t *cond);

可以销毁一个条件变量cond,使其未初始化。一个被引用的条件变量是不可被销毁的,使用一个被销毁的条件变量将造成为止的后果,在默认条件下测试,将导致线程将直处于阻塞状态。

3、等待一个条件变量:

   int pthread_cond_timedwait(pthread_cond_t *cond,pthread_mutex_t *mutex, const struct timespec *restrict abstime);
   int pthread_cond_wait(pthread_cond_t *restrict
 cond, pthread_mutex_t *restrict mutex);

将导致线程阻塞在条件变量cond,应用程序应确保被mutex锁定的线程调用这些函数,否则可能导致未知错误。

这两个函数在执行开始将自动释放mutex,等待条件变量之后将自动锁定mutex,如果有其它线程正在调用mutex将导致线程阻塞。具体执行过程如下所示:

pthread_mutex_cond_unlock(mutex);

pthread_cond_wait(cond);

pthread_mutex_cond_lock(mutex);

在包含pthread_cond_wait函数的线程结束前一定要释放mutex,否则可能会造成其它等待cond的线程一直阻塞。如果有其它线程获得了互斥锁mutex,也将导致cond的线程阻塞。

4、唤醒一个被cond阻塞的线程:

  int pthread_cond_broadcast(pthread_cond_t *cond);
  int pthread_cond_signal(pthread_cond_t *
cond);

pthread_cond_signal将唤醒一个被阻塞的线程,pthread_cond_broadcast是唤醒所有被阻塞的线程,如果没有被阻塞的线程pthread_cond_signal与pthread_cond_broadcast也将正确返回,但是其产生的信号将不起任何作用。

5、使用pthread_cond_timedwait实现精确延时,在单个线程中的cond与mutex可以直接用下面方式实现精确延时:

 

void set_abswaittime(struct timespec*outtime, int ms)
{

  long sec ;
  long usec ;
  struct timeval tnow;
  gettimeofday(&tnow, NULL);
  usec = tnow.tv_usec + ms*1000;
  sec = tnow.tv_sec+usec/1000000;
  outtime->tv_nsec=(usec%1000000)*1000;
  outtime->tv_sec=sec;
}

pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
struct timespec abstime;
set_abswaittime(&abstime,1000);
pthread_cond_wait(&tcond, &tmutex, &abstime);    

6、条件变量使用测试,测试代码如下:

//
// 创建人: levy
// 创建时间:May 25, 2017
// 功能:main.c
// Copyright (c) 2016 levy. All Rights Reserved.
// Ver          变更日期        负责人                           变更内容
// ──────────────────────────────────────────────────────────────────────────
// V0.01         May 25, 2017                  levy          初版
// 

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>

pthread_mutex_t test_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t test_cond=PTHREAD_COND_INITIALIZER;

int test_count;

void * test_thread1(void *arp)
{
    int s=(int)arp;
    printf("I am thread %ld ,I will sleep %d s .\n",pthread_self(),s);   sleep(s);
    pthread_mutex_lock(&test_mutex);

    pthread_cond_wait(&test_cond,&test_mutex);
    test_count++;
    printf("my thread id is %ld ,testcount=%d \n",pthread_self(),test_count);
    pthread_mutex_unlock(&test_mutex);
    pthread_exit(NULL);
}

int  main(void )
{
    pthread_t th[3];
    test_count=0;
    for(int i=0;i<3;i++)
    {
        pthread_create(&th[i],NULL,test_thread1,i);
    }

    for(int i=0;i<3;i++)
    {     sleep(3);
        pthread_cond_signal(&test_cond);
    }
    for(int i=0;i<3;i++)
    {
        pthread_join(th[i],NULL);
    }

    pthread_exit(NULL);
}

输出结果:

I am thread 140391800571648 ,I will sleep 1 s .
I am thread 140391808964352 ,I will sleep 1 s .
I am thread 140391792178944 ,I will sleep 1 s .
my thread id is 140391808964352 ,testcount=1
my thread id is 140391800571648 ,testcount=2
my thread id is 140391792178944 ,testcount=3

如有错误,谢谢指正!

更新:2017-06-02 15:54:50

参考资料:http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_cond_broadcast.html#tag_16_418

时间: 2024-10-30 04:30:19

Linux c 条件变量cond的使用记录的相关文章

linux系统编程:线程同步-条件变量(cond)

线程同步-条件变量(cond) 生产者与消费者问题 再引入条件变量之前,我们先看下生产者和消费者问题:生产者不断地生产产品,同时消费者不断地在消费产品. 这个问题的同步在于两处:第一,消费者之间需要同步:同一件产品只可由一人消费.第二,当无产品可消费时,消费者需等待生产者生产后,才可继续消费,这又是一个同步问题.详细了解:生产者消费者问题. 条件变量 条件变量是利用线程间共享的全局变量进行同步的一种机制,并且条件变量总是和互斥锁结合在一起. 相关函数 pthread_cond_t //条件变量类

Go语言编程:使用条件变量Cond和channel通道实现多个生产者和消费者模型

如题,使用条件变量Cond和channel通道实现多个生产者和消费者模型.Go语言天生带有C语言的基因,很多东西和C与很像,但是用起来 绝对比C语言方便.今天用Go语言来实现下多消费者和生产者模型.如果对C语言的多生产者和消费者模型感兴趣的可以看Linux系统编程:使用mutex互斥锁和条件变量实现多个生成者和消费者模型 代码实现代码实现用了Cond条件变量和channel通道. package main import ( "fmt" "math/rand" &qu

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线程条件变量成为取消点的陷阱

Linux线程条件变量成为取消点的陷阱 使用 pthread_cancel() 时,线程往往不会直接退出,而需要运行到取消点. pthread_cond_wait() 作为线程常见的一种阻塞,它也是一个取消点.所以,处于条件变量阻塞的线程在接收到取消信号就会直接退出. 然而,由于条件变量需要搭配互斥量使用,进入 pthread_cond_wait() 意味着互斥量上锁,此时退出线程如果不进行解锁,而且同时其他线程正在等待此条件变量,那么就会陷入死锁.因此建议使用cleanup函数在线程退出时对互

(转载)Linux 多线程条件变量同步

条件变量是线程同步的另一种方式,实际上,条件变量是信号量的底层实现,这也就意味着,使用条件变量可以拥有更大的自由度,同时也就需要更加小心的进行同步操作.条件变量使用的条件本身是需要使用互斥量进行保护的,线程在改变条件状态之前必须首先锁住互斥量,其他线程在获得互斥量之前不会察觉到这种改变,因为互斥量必须在锁定之后才能计算条件. 模型 #include<pthread.h> pthread_cond_t cond //准备条件变量 pthread_cond_t cond = PTHREAD_CON

笔记3 linux 多线程 条件变量+互斥锁

//cond lock #include<stdio.h> #include<unistd.h> #include<pthread.h> struct test { char a[10]; char b[10]; char c[10]; }yb = {"111","222","33333"}; static int j=0; pthread_mutex_t mutex_1 = PTHREAD_MUTEX_INI

详解linux互斥锁 pthread_mutex和条件变量pthread_cond

[cpp] view plaincopy ============================================================= int pthread_create( pthread_t *tid, const pthread_attr_t *attr, void*(*start_routine)(void*), void *arg ); //参数tid 用于返回新创建线程的线程号: //start_routine 是线程函数指针,线程从这个函数开始独立地运

四十一、Linux 线程——线程同步之条件变量

41.1 概念 41.1.1 条件变量的介绍 互斥锁的缺点是它只有两种状态:锁定和非锁定 条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足 条件变量内部是一个等待队列,放置等待的线程,线程在条件变量上等待和通知,互斥锁用来保护等待队列(对等待队列上锁),条件变量通常和互斥锁一起使用 条件变量允许线程等待特定条件发生,当条件不满足时,线程通常先进入阻塞状态,等待条件发生变化.一旦其它的某个线程改变了条件,可唤醒一个或多个阻塞的线程 具体的判断条件还需用户给出 条件变量数据类

线程同步——条件变量

1.互斥量的存在问题:     互斥量是线程程序必需的工具,但它们并非万能的.例如,如果线程正在等待共享数据内某个条件出现,那会发生什么呢?它可以重复对互斥对象锁定和解锁,每次都会检查共享数据结构,以查找某个值.但这是在浪费时间和资源,而且这种繁忙查询的效率非常低. 在每次检查之间,可以让调用线程短暂地进入睡眠,比如睡眠三秒钟,但是因此线程代码就无法最快作出响应.真正需要的是这样一种方法:当线程在等待满足某些条件时使线程进入睡眠状态.一旦条件满足,就唤醒因等待满足特定条件而睡眠的线程.如果能够做