一. 实验目的

实现一个c程序,该程序能模拟解决有限缓冲问题,其中消费者和生产者产生和消耗随机数

二.实验内容

  1. 缓冲区

元数据类型为buffer_item,大小为1000的数组,按环形队列处理

  1. 生产者和消费者线程

生产者不断执行如下两个操作:消费一个随机数,生产两个随机数

消费者不断执行如下两个操作:生产一个随机数,消费两个随机数

3.Pthead线程创建

使用pthread_create创建5个生产者线程,5个消费者线程,主程序等待所有线程退出

三. 实验环境

Ubuntu Gnome 14.04

MinGW 4.8.1

Codeblocks 13.12

四.实验结果

基本采用semaphore实现了题目要求,其中

psem用于标示是否可生产(数量是否超过缓冲区大小),初始量为1000,每次消费+1,

csem用于标示是否可消费,初始量为0,每次生产+1,

sem用于标示是否可以修改缓冲区

但是以下情况会发生,导致程序死锁:

例如:5个消费者生产5个随机数,随后消耗这5个随机数,则生产者无法先消耗随机数再生产

五.附录

调试心得:
1.  有限缓冲问题确实可能死锁
2.  Pthread_create(tid,attr,func_name,arg)最后一个参数表示唯一传给线程的参数
3.  Void *func_name(void *arg)return需要用pthread_exit(),这个函数的作用是,终止调用它的线程并返回一个指向某个对象的指针,但是直接调用exit(0)会使整个进程退出. 如果主线程调用了pthread_exit,那么它退出了,子线程也不会退出。如果是return 0则会直接退出.
4.  使用函数pthread_exit退出线程,这是线程的主动行为;由于一个进程中的多个线程是共享数据段的,因此通常在线程退出之后,退出线程所占用的资源并不会随着线程的终止而得到释放,但是可以用pthread_join()函数来同步并释放资源。在Linux中,默认情况下是在一个线程被创建后,必须使用此函数对创建的线程进行资源回收,但是可以设置Threads attributes来设置当一个线程结束时,直接回收此线程所占用的系统资源
5.  在线程函数在编译时,需要连接库函数, -lpthread
 
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef int item;
const int bsize = ;
const int pnum = ;
const int cnum = ;
const int looptimes = ;
sem_t sem,psem,csem; struct que{
item a[bsize];
int head,tail,n;
que(){
memset(a,,sizeof(a));
head=tail=n=;
}
}q; void p(char * str,int num){
while(num--){
sem_wait(&psem);
sem_wait(&sem);
q.a[q.head]=rand()%;
q.n++;
printf("%s: produce a[%d]:%d, now there is %d numbers in queue\n",str,q.head,q.a[q.head],q.n);
q.head=(q.head+)%bsize;
sem_post(&csem);
sem_post(&sem);
}
} void c(char *str,int num){
while(num--){
sem_wait(&csem);
sem_wait(&sem);
q.n--;
printf("%s: consume a[%d]:%d, now there is %d numbers in queue\n",str,q.tail,q.a[q.tail],q.n);
q.tail=(q.tail+)%bsize;
sem_post(&psem);
sem_post(&sem);
}
} void * producer(void * arg){
for(int i=;i<looptimes;i++){
c((char*)arg,);
p((char*)arg,);
}
pthread_exit();
}
void * consumer(void * arg){
for(int i=;i<looptimes;i++){
p((char*)arg,);
c((char*)arg,);
}
pthread_exit();
}
int main(){
sem_init(&sem,,);
sem_init(&psem,,);
sem_init(&csem,,);
char pname[][]={"p1","p2","p3","p4","p5"};
char cname[][]={"c1","c2","c3","c4","c5"};
pthread_t ptid[],ctid[];
pthread_attr_t pattr[],cattr[];
for(int i=;i<;i++){
pthread_attr_init(pattr+i);
pthread_create(ptid+i,pattr+i,producer,pname[i]);
pthread_attr_init(cattr+i);
pthread_create(ctid+i,cattr+i,consumer,cname[i]);
}
for(int i=;i<;i++){
pthread_join(ptid[i],NULL);
pthread_join(ctid[i],NULL);
}
puts("end");
return ;
}

Operating System Concepts 项目:生产者-消费者问题 线程的更多相关文章

  1. 生产者消费者模式-->线程

    #_author:来童星#date:2019/12/17#生产者消费者模式-->线程from queue import Queueimport random,time,threading#生产者 ...

  2. 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程

    进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...

  3. python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02

    目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...

  4. Operating System Concepts with java 项目: Shell Unix 和历史特点

    线程间通信,fork(),waitpid(),signal,捕捉信号,用c执行shell命令,共享内存,mmap 实验要求: 1.简单shell: 通过c实现基本的命令行shell操作,实现两个函数, ...

  5. 生产者-消费者模型-线程安全队列Queue

    #python3 #product new data into the queue #comsume data from the queue from queue import Queue impor ...

  6. c++11 条件变量 生产者-消费者 并发线程

    http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-vari ...

  7. Java多线程-同步:synchronized 和线程通信:生产者消费者模式

    大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...

  8. 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操

    昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...

  9. Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

随机推荐

  1. maven核心概念4

    一.Maven坐标 1.1.什么是坐标? 在平面几何中坐标(x,y)可以标识平面中唯一的一点. 1.2.Maven坐标主要组成 groupId:组织标识(包名) artifactId:项目名称 ver ...

  2. wireshark使用教程

    Wireshark: https://www.wireshark.org/ 安装: apt-get install wireshark 教程: http://blog.csdn.net/leichel ...

  3. GO语言中间的derfer

    defer Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句.当函数执行到最后时,这些defer语句会按照逆序执行, 最后该函数返回.特别是当你在进行一些打开资 ...

  4. 彻底理解ThreadLocal

    ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  5. Perl 语法 - 高级特性

    总结: q().qq().qw(同单引号).qx{牢记是花括号},分别是单引号.双引号.创建字符串列表 和 捕获命令输出.   第9学时 其他函数和运算符 一件事情可以使用多种方法完成. 有哪些其他的 ...

  6. centos7 最小化安装 无 ifconfig,netstat 的安装

    centos7 最小化安装 无 ifconfig,netstat 的安装 centos7 最小化安装之后,默认是没有 ifconfig,netstat命令的: 我们可以直接使用 yum -y inst ...

  7. MySQL高可用性分析

    版权声明:本文由易固武原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/203 来源:腾云阁 https://www.qclo ...

  8. noip2016赛后总结

    面前并不是一颗变质的心. 只是一种综合并适应一切的情怀. 这或许是最好的心态... 今年的noip貌似考得好不理想呢...彻底挂了... gjs580,hgr555. 一个初三学弟570,一个400+ ...

  9. IoC 之 2.3 IoC的配置使用(叁)

    2.3.1  XML配置的结构 一般配置文件结构如下: <beans> <import resource="resource1.xml"/> <bea ...

  10. wordpress内存不足问题“Fatal error:out of memoryin etc...”

    2016年3月22日wordpress用户名及密码登录,出现: “ Fatal error: Out of memory (allocated 19136512) (tried to allocate ...