线程的同步与互斥---生产者消费者模型

生产者与消费者模型

生产者与消费者模型是一种描述进程间同步与互斥的一个方式,在这个模式下有两类人,一个是不停产生数据的生产者,一个是不停获取数据的消费者,为了效率最高,就必须保持两者之间的同步与互斥。

为了在生产者与消费者使用mutex保持互斥的前提下,posix版本下还有另外一个函数cond它的作用是在生产者生产出来一个数据时便提醒消费者,而消费者在没东西消费时可以使用cond将自己保持在一个等待生产者信号和关闭锁的状态,当收到信号时将锁打开然后消费。

这是cond的创建与销毁:

       #include <pthread.h>

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

cond的发送信号的函数

       #include <pthread.h>

       int pthread_cond_broadcast(pthread_cond_t *cond);//用向所有正在等待该资源产生的进 //程发送信号
       int pthread_cond_signal(pthread_cond_t *cond);//向单个发送

cond的等待函数

       #include <pthread.h>

       int pthread_cond_timedwait(pthread_cond_t *restrict cond,//非阻塞式等待
              pthread_mutex_t *restrict mutex,
              const struct timespec *restrict abstime);
       int pthread_cond_wait(pthread_cond_t *restrict cond,//阻塞式等待
              pthread_mutex_t *restrict mutex);

代码实现:

缓冲区模型为一个头插头删的链表

单个消费者和单个生产者:

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 #include<pthread.h>
  4 
  5 pthread_mutex_t comm = PTHREAD_MUTEX_INITIALIZER;
  6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  7 
  8 typedef int data_type;
  9 typedef struct list{
 10     data_type _data;
 11     struct list *_next;
 12 }list;
 13 void init_list(list *head)
 14 {
 15     head->_next=NULL;
 16 }
 17 void push(list *head,data_type data)
 18 {
 19     if(head->_next==NULL)
 20     {
 21         list *tmp=(list*)malloc(sizeof(list));
 22         tmp->_data=data;                                                             
 23         tmp->_next=NULL;
 24         head->_next=tmp;
 25     }
 26     else{
 27         list *tmp=(list*)malloc(sizeof(list));
 28         tmp->_next=head->_next;
 29         tmp->_data=data;
 30         head->_next=tmp;
 31     }
 32 }
 33 
 34 int pop(list *head,data_type*data)
 35 {
 36     if(head->_next==NULL)
 37     {
 38         return -1;
 39     }
 40     else
 41     {
 42         *data=head->_next->_data;
 43         list *tmp=head->_next;
 44         head->_next=tmp->_next;
 45         free(tmp);
 46         return 0;
 47     }
 48 }
 49 
 50 void display_list(list *head)
 51 {
 52     list *tmp=head->_next;
 53     while(tmp!=NULL)
 54     {
 55         printf("%d",tmp->_data);
 56         fflush(stdout);
 57         tmp=tmp->_next;
 58     }
 59 }
 60 list head;
 61 
 62 void * producter(void *arg)
 63 {
 64     int i=0;
 65     while(1)
 66     {
 67         pthread_mutex_lock(&comm);
 68         push(&head,i);
 69         pthread_mutex_unlock(&comm);
 70         printf("producter :%d\n",i++);
 71         pthread_cond_broadcast(&cond);
 72         sleep(1);
 73     }
 74 }
 75 void * constumer(void *arg)
 76 {
 77     data_type data;
 78     sleep(10);
 79     while(1)
 80     {
 81             sleep(1);
 82         pthread_mutex_lock(&comm);
 83         while(pop(&head,&data)<0)
 84         {
 85             pthread_cond_wait(&cond,&comm);
 86             printf("buff is empty\n");
 87         }
 88         printf("constumer :%d\n",data);
 89         pthread_mutex_unlock(&comm);
 90     }
 91 }
 92 int main()
 93 {
 94     init_list(&head);
 95     pthread_t _producter,_constumer;
 96     pthread_create(&_producter,NULL,producter,NULL);
 97     pthread_create(&_constumer,NULL,constumer,NULL);
  98     pthread_join(_producter,NULL);
 99      pthread_join(_constumer,NULL);
100
101
102     return 0;
103 }




时间: 2024-10-10 05:56:31

线程的同步与互斥---生产者消费者模型的相关文章

Linux--Condition Variable(条件变量)实现生产者-消费者模型

一.条件变量 在线程同步过程中还有如下的情况:线程A需要等某个条件成立之后才能继续往下执行,如果条件不成立,线程A就阻塞,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行.在Pthread库中用条件变量阻塞等待一个条件,或者唤醒等待这个条件的线程.条件变量用pthread_cond_t类型的变量来表示. 用pthread_cond_init 初始化条件变量.如果条件变量是静态分配的,也可以用宏定义          PTHEAD_COND_INITIALIZER初始化,用pthread

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

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

python并发编程之多进程(二):互斥锁(同步锁)&amp;进程其他属性&amp;进程间通信(queue)&amp;生产者消费者模型

一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终端 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例子 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

13 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件  queue队列 生产者消费者模型 Queue队列 开发一个线程池

本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入输入机,然后启动输入机把

进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: 1 import paramiko 2 # 创建SSH对象 3 ssh = paramiko.SSHClient() 4 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 # 连接服务器 8 ss

生产者消费者模型中线程怎样正常退出

生产者:不停地往队列中放数据 消费者:不停地从队列中拿数据 两者通过两个信号量同步 当生产者不再生产数据时,消费者正好挂在一个信号量上,处于睡眠状态,这时候pthread_join也会一直挂着的.该怎样使得消费者正常退出呢? 我的做法是让生产者在往队列中放一个[结束数据],也就是一个标识,消费者拿到数据后,如果这个数据是结束标识则自杀退出. 生产者消费者模型中线程怎样正常退出

Linux平台下线程同步,实现“生产者消费者问题”

(1)线程同步,实现"生产者消费者问题" 要求:缓冲区大小为20,生产者每次放一个产品,消费者每次取走一个产品:生产者和消费者至少2个. (2)代码如下: #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <sched.h> void *producter_f (void *arg); /*生产者*/ void *consumer_f (void *a

35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型

守护进程 进程:一个正在运行的程序. 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止, 2.守护进程内无法再开启子进程,否则抛出异常. 注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止. 例子:from multiprocessing import Processimport time def task(): print('老了....') time.sleep(2) print('睡了一会..') if __name__ == '__main__': prin