互斥量就是一把锁,在访问数据时能保证同一时间内只有一个线程访问数据,在访问完以后再释放互斥量上的锁。

  条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。

  条件变量应该和互斥量配合使用,以避免出现条件竞争,一个线程预备等待一个条件变量,当它在真正进入等待之前,另一个线程恰好触发了该条件.

  条件变量采用的数据类型是pthread_cond_t,在使用之前必须要进行初始化,与互斥锁类型,也包括两种方式.
  静态初始化:可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量;
  动态初始化:在申请内存(malloc)后,通过pthread_cond_init进行初始化.注意在释放内存前需要调用pthread_cond_destory.动态方式调用pthread_cond_init()函数,API定义如下:

    int   pthread_cond_init(pthread_cond_t   *cond,   pthread_condattr_t   *cond_attr)    

  结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用;如果选择为PTHREAD_PROCESS_SHARED则为多个进程间各线程公用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。

  int   pthread_cond_wait(pthread_cond_t   *cond,   pthread_mutex_t   *mutex)   
  int   pthread_cond_timedwait(pthread_cond_t   *cond,   pthread_mutex_t   *mutex,   const   struct   timespec   *abstime)    
    
  等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。  
    
  无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race   Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。   
    
  激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct node {
int n_number;
struct node *n_next;
} *head = NULL; /*[thread_func]*/
static void cleanup_handler(void *arg)
{
printf("Cleanup handler of second thread.\n");
free(arg);
(void)pthread_mutex_unlock(&mtx);
}
static void *thread_func(void *arg)
{
struct node *p = NULL; pthread_cleanup_push(cleanup_handler, p);
while () {
pthread_mutex_lock(&mtx);
while (head == NULL) {
pthread_cond_wait(&cond, &mtx); }
p = head;
head = head->n_next;
printf("Got %d from front of queue\n", p->n_number);
free(p);
pthread_mutex_unlock(&mtx);
}
pthread_cleanup_pop();
return ;
} int main(void)
{
pthread_t tid;
int i;
struct node *p;
pthread_create(&tid, NULL, thread_func, NULL);
/*[tx6-main]*/
for (i = ; i < ; i++) { p = malloc(sizeof(struct node));
p->n_number = i;
pthread_mutex_lock(&mtx);
p->n_next = head;
head = p;
pthread_cond_signal(&cond); pthread_mutex_unlock(&mtx);
sleep();
}
printf("thread 1 wanna end the line.So cancel thread 2.\n");
pthread_cancel(tid);
pthread_join(tid, NULL);
printf("All done -- exiting\n");
return ;
}

linux 条件变量的更多相关文章

  1. 理解 Linux 条件变量

    理解 Linux 条件变量 1 简介 当多个线程之间因为存在某种依赖关系,导致只有当某个条件存在时,才可以执行某个线程,此时条件变量(pthread_cond_t)可以派上用场.比如: 例1: 当系统 ...

  2. linux 条件变量与线程池

    条件变量Condition Variables 概述 1. 条件变量提供了另外一种线程同步的方式.如果没有条件变量,程序需要使用线程连续轮询(可能在临界区critical section内)方式检查条 ...

  3. linux条件变量

    条件变量用于线程之间的通信,和互斥锁一起使用.条件变量用于及时通知等待的线程条件的变化,使线程不至于错过变化. 考虑下面的情况,有AB两个线程对index这个全局变量进行++,一个线程C用于判断,in ...

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

    近来在项目中用到条件变量和信号量做同步时,这一块一直都有了解,但也一直没有总结,这次总结一下,给大家提供点参考,也给自己留点纪念. 首先,关于信号量和条件变量的概念可以自行查看APUE,我这直接把AP ...

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

    pthread_cond_wait必须放在pthread_mutex_lock和pthread_mutex_unlock之间,因为他要根据共享变量的状态来觉得是否要等待,而为了不永远等待下去所以必须要 ...

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

    Linux C语言多线程库Pthread中条件变量的的正确用法逐步详解   多线程c语言linuxsemaphore条件变量 (本文的读者定位是了解Pthread常用多线程API和Pthread互斥锁 ...

  7. [转]一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程

    一个简单的Linux多线程例子 带你洞悉互斥量 信号量 条件变量编程 希望此文能给初学多线程编程的朋友带来帮助,也希望牛人多多指出错误. 另外感谢以下链接的作者给予,给我的学习带来了很大帮助 http ...

  8. linux多线程-互斥&条件变量与同步

    多线程代码问题描述 我们都知道,进程是操作系统对运行程序资源分配的基本单位,而线程是程序逻辑,调用的基本单位.在多线程的程序中,多个线程共享临界区资源,那么就会有问题: 比如 #include < ...

  9. linux多线程同步pthread_cond_XXX条件变量的理解

    在linux多线程编程中,线程的执行顺序是不可预知的,但是有时候由于某些需求,需要多个线程在启动时按照一定的顺序执行,虽然可以使用一些比较简陋的做法,例如:如果有3个线程 ABC,要求执行顺序是A-- ...

随机推荐

  1. Data Base sqlServer DataReader与DataSet的区别

    sqlServer   DataReader与DataSet的区别 从以下这几个方面比较: 1.与数据库连接: DataReader:面向连接,只读,只进,只能向前读,读完数据就断开连接: DataS ...

  2. linux ps top 命令 VSZ,RSS,TTY,STAT, VIRT,RES,SHR,DATA的含义【转】

    转自:http://blog.csdn.net/zjc156m/article/details/38920321 http://javawind.net/p131 VIRT:virtual memor ...

  3. YTU 2601: 熟悉题型——填空题(删除线性表节点)

    2601: 熟悉题型--填空题(删除线性表节点) 时间限制: 1 Sec  内存限制: 128 MB 提交: 357  解决: 212 题目描述 给出一串具体长度的数据,删除指定数据. 已经给出部分代 ...

  4. 7.cadence原理图后续[原创]

    一.网表输出 1.自动编号 输出网表前,不能有问号 -- 效果: ---- -- 效果: 2.DRC检查 输出网表前需要DRC检查 3.网表输出 二.生成BOM表 法1: 法2: --- 点击OK: ...

  5. 收藏一些python的小技能

    例子1:For .. else 语法 foo=[2,1] for i in foo: if i == 0: break else: print("i was never 0") 例 ...

  6. sdut2169Sequence(dp)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2169 感觉是有递归思想的 dp[j]表示从1到 ...

  7. bzoj2982: combination

    借(cao)鉴(xi)自popoqqq大爷的lucas定理的写法 #include<cstdio> #include<cstring> #include<cctype&g ...

  8. MVC+Ef项目(2) 如何更改项目的生成顺序;数据库访问层Repository仓储层的实现

    我们现在先来看看数据库的生成顺序   居然是 Idal层排在第一,而 web层在第二,model层反而在第三 了   我们需要把 coomon 公用层放在第一,Model层放在第二,接下来是 Idal ...

  9. BZOJ 1106 立方体大作战

    BIT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&g ...

  10. BZOJ 1003 物流运输

    最短路+dp. #include<iostream> #include<cstdio> #include<cstring> #include<algorith ...