Operating System Concepts 项目:生产者-消费者问题 线程
一. 实验目的
实现一个c程序,该程序能模拟解决有限缓冲问题,其中消费者和生产者产生和消耗随机数
二.实验内容
- 缓冲区
元数据类型为buffer_item,大小为1000的数组,按环形队列处理
- 生产者和消费者线程
生产者不断执行如下两个操作:消费一个随机数,生产两个随机数
消费者不断执行如下两个操作:生产一个随机数,消费两个随机数
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 项目:生产者-消费者问题 线程的更多相关文章
- 生产者消费者模式-->线程
#_author:来童星#date:2019/12/17#生产者消费者模式-->线程from queue import Queueimport random,time,threading#生产者 ...
- 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程
进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...
- python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02
目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...
- Operating System Concepts with java 项目: Shell Unix 和历史特点
线程间通信,fork(),waitpid(),signal,捕捉信号,用c执行shell命令,共享内存,mmap 实验要求: 1.简单shell: 通过c实现基本的命令行shell操作,实现两个函数, ...
- 生产者-消费者模型-线程安全队列Queue
#python3 #product new data into the queue #comsume data from the queue from queue import Queue impor ...
- c++11 条件变量 生产者-消费者 并发线程
http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-vari ...
- Java多线程-同步:synchronized 和线程通信:生产者消费者模式
大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...
- 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操
昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...
- Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
随机推荐
- java SE (java Standard Edition)
14.10.22 学习java SE的Object: -------------------------------------15.11.18----
- mysql 变量
用户变量 1.用户变量,用户变量和数据库连接有关,连接后声明变量,连接断开后,自动消失. 2.用户变量以@开头,select一个没有赋值的用户变量,返回NULL,也就是没有值,注意取值为NULL与取值 ...
- 强行替换exe图标的方法
说句实话,要想用普通的方法来替换图标,不是完全不可行,当然也不是完全可行.这个看似简单的问题并不是想象中那么容易解决,为什么有人修改exe的图标总是失败,其实他忽视了exe和图标的复杂性,用简单的方法 ...
- 代码中特殊的注释技术——TODO、FIXME和XXX的用处
本文内容概要: 代码中特殊的注释技术--TODO.FIXME和XXX的用处. 前言:今天在阅读Qt Creator的源代码时,发现一些注释中有FIXME英文单词,用英文词典居然查不到其意义!实际上, ...
- HTTP POST GET 本质区别详解
HTTP POST GET 本质区别详解 一 原理区别 一般在浏览器中输入网址访问资源都是通过GET方式:在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交 Ht ...
- 【linux命令】grep
1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局 ...
- ubuntu sudo apt-get update 失败 解决方法
sudo apt-get update 报了一堆错误: Err http://cn.archive.ubuntu.com trusty InRelease Err http://cn.archive. ...
- QQ聊天即时代码
QQ即时聊天代码:[需对方已经即时聊天工具功能 开通入口http://shang.qq.com/v3/widget.html] tencent://Message/?Uin=84065994& ...
- matlab中图像显示函数
image函数是显示图像的最基本的方法.该函数还产生了图像对象的句柄,并允许对对象的属性进行设置. imagesc函数也具有image的功能,所不同的是imagesc函数还自动将输入数据比例化,以全色 ...
- phalcon: 查找记录(Finding Records)可用的查询设置如下:
可用的查询设置如下: 参数 描述 举例 conditions Search conditions for the find operation. Is used to extract only tho ...