线程同步与互斥之条件·变量

条件变量(condition variable)

线程间的同步与互斥技术,主要以互斥锁和条件变量为主,条件变量和互斥所的配合使用可以很好的处理对于条件等待的线程间的同步问题。举个例子:消费者和生产者问题。

消费者与生产者最基本的关系是服务与被服务的关系,但是在线程同步与互斥中强调的是两者访问资源的关系。首先生产与消费的关系为:同步与互斥,生产与生产的关系为:互斥,消费与消费的关系为:互斥。所以维护这三种关系的有两类人:生产者与消费者。并且生产数据与消费数据必须有场所。

所以将其简述为三种关系两类人一个场所(当然这里的场所并不是只能有一个,可以是多样的)。

介绍条件变量的几个函数:

1.定义一个条件变量

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

2.初始化条件变量(当定义没初始化时)

int pthread_cond_init(pthread_cond_t *restrict cond,

const pthread_condattr_t *restrict attr);

3.销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond)

举一个单个消费者与单个生产者问题:

  1 #include<stdio.h>
  2 #include<pthread.h>
  3 #include<assert.h>
  4 #include<stdlib.h>
  5 pthread_cond_t cond;
  6 typedef int data_type;
  7 pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
  8 void push_node(data_type data);
  9 int pop_node();
 10 void* producter(void* arg)
 11 {
 12     data_type i=0;
 13     while(1)
 14    {
 15       pthread_mutex_lock(&lock);
 16       i++;
 17       push_node(i);
 18       sleep(2);
 19       pthread_mutex_unlock(&lock);
 20       printf("product done......\n");
 21       sleep(2);
 22       pthread_cond_signal(&cond);
 23       sleep(2);
 25     }
 26 
 27 }
 28 void *consumer(void* arg)
 29 {
 30     data_type res=-1;
 31    while(1)
 32    {
 33       pthread_mutex_lock(&lock);
 34       while(-1==pop_node(&res))
 35         {
 36          pthread_cond_wait(&cond,&lock);
 37          }
 38         res=pop_node(&res);
 39         printf("consumer data: %d\n",res);
 40         sleep(2);
 41         pthread_mutex_unlock(&lock);
 44         pthread_cond_signal(&cond);
 45         sleep(2);
 46 
 47     }
 48 
 49 }
 50 
 51 typedef struct _node
 52 {
 53  data_type    _data;
 54  struct _node* _next;
 55 }node, *node_p,**node_pp;
 56 
 57 node_p head=NULL;
 58  static node_p buy_node(data_type data)
 59 {
 60    node_p tmp=malloc(sizeof(node));
 61    if(tmp==NULL)
 62      {
 63        printf("malloc failed\n");
 64 
 65       }
 66      tmp->_data=data;
 67      tmp->_next=NULL;
 68      return tmp;
 69 }
 71 void init_list(node_pp phead)
 72 {
 73      *phead=buy_node(0);
 74 }
 75 
 76 void push_node(data_type data)
 77 {
 78   
 79    if(head->_next==NULL)
 80        head->_next=buy_node(data);
 81    else{
 82      node_p tmp=buy_node(data);
 83      tmp->_next=head->_next;
 84      head->_next=tmp;
 85      }
 86 }
 87 
 88 
 89 int pop_node(data_type *data)
 90 { data_type ret=0;
 91  
 92   if(head->_next==NULL)
 93       return *data;
      else{
 95    node_p tmp=head->_next;
 96    head->_next=tmp->_next;
 97    *data=tmp->_data;
 98   free(tmp);
 99    }
100   return *data;
101 }
102 int main()
103 {
104 
105   init_list(&head);
106   pthread_cond_init(&cond,NULL);
107   pthread_mutex_init(&lock,NULL);
108   pthread_t tid1,tid2;
109   pthread_create(&tid1,NULL,producter,NULL);
110   pthread_create(&tid2,NULL,consumer,NULL);
111   pthread_join(tid1,NULL);
112   pthread_join(tid2,NULL);
113   pthread_cond_destroy(&cond);
114   pthread_mutex_destroy(&lock);
115   return 0;                                                           
       }

运行结果:

结果分析:

生产者生产出一个数据之后消费者才能消费,当链表里没有数据时,消费者就等待对应的条件变量和锁,直到他们被释放消费者才能进去消费。

扩展:多消费者与多生产者问题

 10 pthread_mutex_t plock=PTHREAD_MUTEX_INITIALIZER;
 11 pthread_mutex_t conlock=PTHREAD_MUTEX_INITIALIZER;
 12 void push_node(data_type data);
 13 int pop_node();
 14 void* producter(void* arg)
 15 {
 16     data_type i=0;
 17     while(1)
 18    {  sem_wait(&sem_product);
 19       pthread_mutex_lock(&plock);
 20       i++;
 21       push_node(i);
 22       sleep(2);
 23       pthread_mutex_unlock(&plock);
 24       sem_post(&sem_consume);
 25       printf("product done......\n");
 26        sleep(2);
 27      pthread_cond_signal(&cond);
 28       sleep(2);
 29 
 30     }
 31 
 32 }
 33 void *consumer(void* arg)
 34 {
 35     data_type res=-1;
 36    while(1)
 37    {
 38       sem_wait(&sem_consume);
 39       pthread_mutex_lock(&conlock);
 40       while(-1==pop_node(&res))
 41         {
 42          pthread_cond_wait(&cond,&plock);
 43          }
 44         res=pop_node(&res);
 45         printf("consumer data: %d\n",res);
 46         sleep(2);
 47         pthread_mutex_unlock(&conlock);
 48 
 49         sem_post(&sem_product);
 50 
 51         pthread_cond_signal(&cond);
 52 
 53         sleep(2);
 54 
 55     }
时间: 2024-11-09 13:27:18

线程同步与互斥之条件·变量的相关文章

线程同步和互斥(条件变量控制生产者消费者模型)

条件变量 生产者消费者模型: 关系:      同步 生产者<----->消费者    互斥 互斥 生产者<----->生产者       互斥 消费者<----->消费者   场所:   缓冲区,下文以链表方式实现 1.单个生产者,单个消费者,且生产者和消费者访问链表的顺序是LIFO的 代码实现: #include<stdio.h> #include<pthread.h> pthread_mutex_t _mutex_lock=PTHREAD_

Windows线程同步【5】条件变量(Condition Variable)

一.引言 假设有一个任务,由我和张三共同完成.张三把寄来的文稿初步审阅后放入一个队列,我负责将这个队列中的文稿进行审批,决定刊登与否.张三审阅一份文稿需要15分钟,我处理一个文稿需要2分钟. 如果将张三和我看作两个线程,那么我们共享一个队列的数据.按照一般的多线程思路,他每隔一段时间往队列中放入数据,我每隔一段时间检查一下队列中是否有数据,若有,则处理之. 若我们按照上面的方式工作,则大部分的时间,我只是在干等着,所以,这是一种比较低效的方式. 但换一种方式之后,情况就好很多了.他每把一个文稿放

嵌入式开发之hi3519---进程线程间的同步和互斥,条件变量、信号了、互斥锁等

sem_post 最安全 sem  有序,会卡顿 阻塞 mutex  无序,不能同步 http://blog.chinaunix.net/uid-20671208-id-4935154.html https://www.cnblogs.com/ngnetboy/p/3521547.html http://www.jianshu.com/p/1e59f0970bf5 http://blog.csdn.net/jenny8080/article/details/52094140

进程间同步(1)&mdash;&mdash;条件变量和互斥量

1. 概述 条件变量和互斥量是最基本的同步形式,总是用于同步同一个进程的各个线程间同步. 当把条件变量或互斥量放在共享内存区时,可用于进程间同步. 同样的情况还有读写锁,它们都是随进程的持续性.   2.互斥锁 互斥锁指代相互排斥,用于保护临界区.多个线程和多个进程分享的共享数据. 静态初始化:static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 动态初始化:互斥锁是动态分配的,pthread_mutex_init(&mutex);初始

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.   

Android多线程研究(3)——线程同步和互斥及死锁

为什么会有线程同步的概念呢?为什么要同步?什么是线程同步?先看一段代码: package com.maso.test; public class ThreadTest2 implements Runnable{ private TestObj testObj = new TestObj(); public static void main(String[] args) { ThreadTest2 tt = new ThreadTest2(); Thread t1 = new Thread(tt,

多个生产者——多个消费者模型(互斥量条件变量实现)

1. 介绍 生产者消费者问题属于有界缓冲区问题.我们现在讲述多个生产者向一个缓冲区中存入数据,多个生产者从缓冲区中取数据. 共享缓冲区作为一个环绕缓冲区,存数据到头时再从头开始. 2. 实现 我们使用一个互斥量保护生产者向缓冲区中存入数据. 由于有多个生产者,因此需要记住现在向缓冲区中存入的位置. 使用一个互斥量保护缓冲区中消息的数目,这个生产的数据数目作为生产者和消费者沟通的桥梁. 使用一个条件变量用于唤醒消费者.由于有多个消费者,同样消费者也需要记住每次取的位置. 4.代码 在选项中选择生产

一起talk C栗子吧(第一百一十六回:C语言实例--线程同步之互斥量二)

各位看官们,大家好,上一回中咱们说的是线程同步之信号量的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中详细介绍了互斥量相关函数的用法,这一回中,我们介绍如何使用这些函数来操作互斥量. 下面是详细的操作步骤: 1.定义一个互斥量A,用来同步线程: 2.在创建线程的进程中使用pthread_mutex_init函数初始化互斥量,互斥量的属性使用默认值: 3.在读取数据的线程中读取数据,首先使用pthread_mutex_lock函数对互斥量A进行加锁

C#学习笔记---线程同步:互斥量、信号量、读写锁、条件变量

http://www.cnblogs.com/maxupeng/archive/2011/07/21/2112282.html 一.互斥量(mutex) 互斥量本质上是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁. 对互斥量进行加锁以后,任何其它试图再次对互斥量加锁的线程将会被阻塞直到当前线程释放该互斥锁.如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量加锁,其它线程将会看到互斥锁依然被锁住,只能回去再次