生产者和消费者代码

合集下载

生产者消费者伪码_[线程同步]生产者消费者代码实现

生产者消费者伪码_[线程同步]生产者消费者代码实现

⽣产者消费者伪码_[线程同步]⽣产者消费者代码实现⽣产者消费者问题是⼀个著名的线程同步问题,该问题描述如下:有⼀个⽣产者在⽣产产品,这些产品将提供给若⼲个消费者去消费,为了使⽣产者和消费者能并发执⾏,在两者之间设置⼀个具有多个缓冲区的缓冲池,⽣产者将它⽣产的产品放⼊⼀个缓冲区中,消费者可以从缓冲区中取⾛产品进⾏消费,显然⽣产者和消费者之间必须保持同步,即不允许消费者到⼀个空的缓冲区中取产品,也不允许⽣产者向⼀个已经放⼊产品的缓冲区中再次投放产品。

⾸先来简化问题,先假设⽣产者和消费者都只有⼀个,且缓冲区也只有⼀个。

这样情况就简便多了。

1. 从缓冲区取出产品和向缓冲区投放产品必须是互斥进⾏的。

可以⽤关键段和互斥量来完成。

2. ⽣产者要等待缓冲区为空,这样才可以投放产品,消费者要等待缓冲区不为空,这样才可以取出产品进⾏消费。

并且由于有两个等待过程,所以要⽤两个事件或信号量来控制。

#include#include#includeCRITICAL_SECTION g_csThreadCode;HANDLE g_EventBuffFull;HANDLE g_EventBuffEmpty;int g_buffer;const int THREAD_NUM = 2;const int product_num = 100;unsigned int __stdcall producer_thread(void *param){for (int i = 0; i < product_num; i++){WaitForSingleObject(g_EventBuffEmpty, INFINITE);EnterCriticalSection(&g_csThreadCode);g_buffer = i;printf("⽣产者在缓冲区中放置⼀个产品,编号%d\n", g_buffer);LeaveCriticalSection(&g_csThreadCode);SetEvent(g_EventBuffFull);}return 0;}unsigned int __stdcall consumer_thread(void *param){for (int i = 0; i < product_num; i++){WaitForSingleObject(g_EventBuffFull, INFINITE);EnterCriticalSection(&g_csThreadCode);printf("消费者取⾛%d产品\n", g_buffer);g_buffer = 0;LeaveCriticalSection(&g_csThreadCode);SetEvent(g_EventBuffEmpty);}Sleep(10);return 0;}int main(){InitializeCriticalSection(&g_csThreadCode);g_EventBuffEmpty = CreateEvent(NULL, false, true, NULL);g_EventBuffFull = CreateEvent(NULL, false, false, NULL);HANDLE handle[THREAD_NUM];handle[0] = (HANDLE)_beginthreadex(NULL, 0, producer_thread, NULL, 0, NULL); handle[1] = (HANDLE)_beginthreadex(NULL, 0, consumer_thread, NULL, 0, NULL); WaitForMultipleObjects(THREAD_NUM, handle, true, INFINITE);//销毁同步资源DeleteCriticalSection(&g_csThreadCode);CloseHandle(handle[0]);CloseHandle(handle[1]);CloseHandle(g_EventBuffFull);CloseHandle(g_EventBuffEmpty);return 0;}代码执⾏结果:可以看出⽣产者与消费者已经是有序的⼯作了。

消费者、生产者Java代码示例,wait-notify实现

消费者、生产者Java代码示例,wait-notify实现

消费者、⽣产者Java代码⽰例,wait-notify实现箱⼦中的苹果代表资源,现在有消费者从箱⼦中拿⾛苹果,⽣产者往箱⼦中放苹果。

代码如下:资源--箱⼦中的苹果:public class Box {int size;int num;public Box(int size, int num) {this.size = size;this.num = num;}public synchronized void put() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}while (num == 10) { //⽤while循环检查更好,在下⾯的wait()结束后还再判断⼀次,防⽌虚假唤醒try {System.out.println("箱⼦满了,⽣产者暂停。

");this.wait(); //等待消费者消费⼀个才能继续⽣产,所以要让出锁} catch (InterruptedException e) {e.printStackTrace();} finally {}}num++;System.out.println("箱⼦有空闲,开始⽣产。

"+num);this.notify(); //唤醒可能因为没苹果⽽等待的消费者}public synchronized void take() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}while (num == 0) { //⽤while循环检查更好,在wait()结束后还再判断⼀次,防⽌虚假唤醒try {System.out.println("箱⼦空了,消费者暂停。

");this.wait(); //等待⽣产者⽣产⼀个才能继续消费,所以要让出锁} catch (InterruptedException e) {e.printStackTrace();} finally {}}num--;System.out.println("箱⼦有了,开始消费。

生产者消费者完整代码

生产者消费者完整代码

// pc.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <time.h>typedef HANDLE Semaphore; // 信号量的Windows原型#define P(S) WaitForSingleObject(S, INFINITE) // 定义Windows下的P操作#define V(S) ReleaseSemaphore(S, 1, NULL) // 定义Windows下的V操作#define rate 1000#define CONSUMER_NUM 2 /* 消费者个数*/#define PRODUCER_NUM 2 /* 生产者个数*/#define BUFFER_NUM 4 /* 缓冲区个数*/char *thing[8] = {"萝卜", "白菜", "豆付", "青菜", "鸡", "鸭", "鱼", "肉"}; //生产和消费的产品名称struct Buffer{int product[BUFFER_NUM]; // 缓冲区int start, end; // 两个指针相当于教材中的in out 指针} g_buf;Semaphore empty, full, mutex; //分别相当于empty, full, mutex三个信号量// 消费者线程DWORD WINAPI Consumer(LPVOID para){// i表示第i个消费者int i = *(int *)para; //利用para传入当前消费者的编号int ptr; // 待消费的内容的指针printf("消费者-%03d: 我来啦!\n", i);int j=0;while (j++<4){//////////////补充代码与此处!!!!!!printf("消费者-%03d: 我要吃.........!\n", i);// 等待产品P(full);// 有产品,先锁住缓冲区P(mutex);// 记录消费的物品ptr = g_buf.start;// 再移动缓冲区指针g_buf.start = (g_buf.start+1)%BUFFER_NUM;// 让其他消费者或生产者使用printf(" 消费者-%03d: 我吃buf[%d] = %s\n", i, ptr, thing[g_buf.product[ptr]]);// 消费完毕,并释放一个缓冲printf(" 消费者-%03d: 我吃完了buf[%d] = %s\n", i, ptr, thing[g_buf.product[ptr]]);V(mutex);V(empty);Sleep(rate*rand()%10+110);}return 0;}// 生产者线程DWORD WINAPI Producer(LPVOID para){int i = *(int *)para - CONSUMER_NUM;int ptr;int data; // 产品printf("生产者-%03d: 我来啦!\n", i);int j=0;while (j++<4){//////////////补充代码与此处!!!!!!printf("生产者-%03d: 我准备生产…………\n", i);data = rand()%8;printf("生产者-%03d: 生产出一个东西data = %s!\n", i, thing[data]);// 等待存放空间P(empty);// 有地方,先锁住缓冲区P(mutex);// 记录消费的物品ptr = g_buf.end;// 再移动缓冲区指针g_buf.end = (g_buf.end+1)%BUFFER_NUM;printf("生产者-%03d: 放到buf[%d] = %s\n", i, ptr, thing[data]);g_buf.product[ptr] = data;// 放好了完毕,释放一个产品printf("生产者-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.product[ptr]]);// 让其他消费者或生产者使用V(mutex);V(full);Sleep(rate/2*rand()%10+110);}return 0;}int main(int argc, char *argv[]){// 线程技术,前面为消费者线程,后面为生产者线程HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 线程计数srand(time(NULL));rand();DWORD tid;int i=0;// 初始化信号量mutex = CreateSemaphore(NULL, 1, 1, "mutexOfConsumerAndProducer"); empty = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");full = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProductSemaphone");if ( !empty || !full || !mutex){printf("Create Semaphone Error!\n");return -1;}int totalThreads = CONSUMER_NUM+PRODUCER_NUM;// 开启消费者线程printf("先请消费者上席!\n");for (i=0; i<CONSUMER_NUM; i++){hThread[i] = CreateThread(NULL, 0, Consumer, &i, 0, &tid);if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);}printf("生产者就位!\n");for (; i<totalThreads; i++){hThread[i] = CreateThread(NULL, 0, Producer, &i, 0, &tid);if ( hThread[i] ) WaitForSingleObject(hThread[i], 10);}// 生产者和消费者的执行WaitForMultipleObjects(totalThreads, hThread, TRUE, INFINITE);return 0;}。

操作系统实验 生产者与消费者问题代码

操作系统实验  生产者与消费者问题代码
m_requestNum=((ThreadInfo*)(p))->n_request;
for (int i=0;i<m_request[i] = ((ThreadInfo*)(p))->thread_request[i]);
sleep(m_delay);
for(i=0;i<m_requestNUM;i++){
{
for (int i=0;i<n_Thread;i++)
for (int j=0;j<Thread_Info[i].n_request;j++)
if(Thread_Info[i].thread_request[j] == req)
return TRUE;
}
int FindProducePosition()
cout<<end1;
}
printf("\n\n");
empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical,"semaphore_for_empty");
h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update");
((ThreadInfo*)(p))->thread_request[i]=-1;
if(!IfInOtherRequest(m_thread_request[i])){
Buffer_Critical[Bufferpos]= -1;
printf("Consumer%2d finish consuming %2d:\n",m_serial,m_thread_request[i]);

生产者与消费者代码

生产者与消费者代码
}
}
//创建缓冲区buffer文件映射对象
void CreateSharedMemory(){
h_buffer = CreateFileMapping(
INVALID_HANDLE_VALUE,//使用页式临时文件
NULL,//缺省的安全性
PAGE_READWRITE,//可读可写
0,
sizeof(Buffer),
(*p_buffer).p[(*p_buffer).in][j] = '1';
}
SYSTEMTIME now;
GetSystemTime(&now); //获取并显示系统时间
printf("At %2d:%2d:%2d:%d a string was produced.\n",now.wHour,now.wMinute,now.wSecond,now.wMilliseconds);
FILE_MAP_ALL_ACCESS,//可读可写
0,
0,
sizeof(Buffer));//映射整个文件
if(hFile =NULL){
printf("Map view of file error!\n");
CloseHandle(h_buffer);
}
else{
ZeroMemory(hFile,sizeof(Buffer));//清零
}
}
//主程序
int main(int argc, char *argv[]){
printf("argv[1]=%s argv[2]=%s\n",argv[1],argv[2]);
//创建互斥体对象
HANDLE Mutex = CreateMutex(

C语言编程模拟生产者与消费者问题附代码程序

C语言编程模拟生产者与消费者问题附代码程序

添加标题 添加标题
性能优化总结:在实现过程中,我们采用了多线程和并发等机制,提高了程序的运行效率和响 应速度,同时也考虑了程序的稳定性和可靠性。
展望未来:在未来的工作中,我们可以进一步探索和研究生产者与消费者问题及其解决方案, 例如使用更高级的并发和分布式技术,提高程序的性能和可扩展性。同时,也可以将该问题 及其解决方案应用于其他领域,例如操作系统、网络通信和数据库等。
消费者从共享缓冲区取出数 据的代码示例
消费者从共享缓冲区取出数 据的过程分析
消费者从共享缓冲区取出数 据需要注意的问题
添加同步机制(互斥锁、条件变量)
互斥锁的使用:通过互斥锁可以保证同一时间只有一个线程可以访问 共享资源,避免数据冲突。
条件变量的使用:条件变量可以用于实现线程间的同步,一个线程可 以在条件变量上等待,直到另一个线程发出通知。
代码程序运行结果展 示
第五章
程序运行截图
生产者程序运行截图
消费者程序运行截图
生产者与消费者程序运行截 图
程序运行结果展示
程序运行结果描述
生产者与消费者问题的模拟过程 代码程序的运行结果展示 生产者与消费者问题的解决效果 代码程序的运行效率和性能评估
结果分析
展示代码程序运行结果 分析代码程序的执行过程 解释代码程序对生产者与消费者问题的解决过程 总结代码程序的优缺点及改进方向
创建生产者线程
生产者线程执行逻辑
生产者线程与消费者 线程交互
生产者线程结束
消费者线程代码实现
创建消费者线程
消费者线程调用 生产者线程
消费者线程接收 生产者线程发送 的消息
消费者线程处理 接收到的消息
共享资源代码实现
共享资源定义:共享资源是生产者和消费者共同使用的资源,需要保证 在任何时刻都不会被多个生产者或消费者同时访问

C语言编程模拟生产者和消费者问题附代码程序

C语言编程模拟生产者和消费者问题附代码程序

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和Visual C++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

[提示]:(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P (s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V (s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedure p (var s: semaphore);begin s: = s-1;if s<0 then W (s)end {p}procedure v (var s: semaphore);egin s: = s+1;if s£0 then R (s)end {v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

计算机操作系统课程设计源代码《生产者---消费者问题源代码》

计算机操作系统课程设计源代码《生产者---消费者问题源代码》

《生产者---消费者问题源代码》#include<stdio.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#include<semaphore.h>#include<sys/types.h>#include<errno.h>#include<unistd.h>#include<signal.h>#include<time.h>#define NUM_THREADS_P5/*定义数据为生产者*/#define NUM_THREADS_C5/*定义数据为消费者*/#define MAX_BUFFER20/*定义数据为缓存区*/#define RUN_TIME20/*定义运行时间*/int buffer[MAX_BUFFER];/*定义最大缓存区*/int produce_pointer=0,consume_pointer=0;/*定义指针*/sem_t producer_semaphore,consumer_semaphore,buffer_mutex;/*定义信号量,互斥*/pthread_t threads_p[NUM_THREADS_P];/*声明生产者线程*/pthread_t threads_c[NUM_THREADS_C];/*声明消费者线程*/FILE*fd;void*producer_thread(void*tid);/*声明生产者线程*/void*consumer_thread(void*tid);/*声明消费者线程*/void showbuf();/*声明showbuf方法*/void handler(){int i;/*定义i*/for(i=0;i<NUM_THREADS_P;i++)pthread_cancel(threads_p[i]);/*for循环,如果i<NUM_THREADS_P,则pthread_cancel(threads_p[i]);并且i++*/ for(i=0;i<NUM_THREADS_C;i++)pthread_cancel(threads_c[i]);/*for循环,如果i<NUM_THREADS_C,则pthread_cancel(threads_c[i]);并且i++*/}int main(){int i;/*定义i*/signal(SIGALRM,handler);/*定义信号量*/fd=fopen("output.txt","w");/*打开一个文件用来保存结果*/sem_init(&producer_semaphore,0,MAX_BUFFER);/*放一个值给信号灯*/sem_init(&consumer_semaphore,0,0);sem_init(&buffer_mutex,0,1);for(i=0;i<MAX_BUFFER;i++)buffer[i]=0;/*引发缓冲*//*创建线程*/for(i=0;i<NUM_THREADS_P;i++)pthread_create(&threads_p[i],NULL,(void*)producer_thread,(void*)(i+1)); /*创建线程*/for(i=0;i<NUM_THREADS_C;i++)pthread_create(&threads_c[i],NULL,(void*)consumer_thread,(void*)(i+1));alarm(RUN_TIME);for(i=0;i<NUM_THREADS_P;i++)pthread_join(threads_p[i],NULL);/*等待线程退出*/for(i=0;i<NUM_THREADS_C;i++)pthread_join(threads_c[i],NULL);/*等待线程退出*/sem_destroy(&producer_semaphore);/*清除信号灯*/sem_destroy(&consumer_semaphore);/*清除信号灯*/sem_destroy(&buffer_mutex);/*清除缓存区*/fclose(fd);/*关闭文件*/return0;}void*producer_thread(void*tid){pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);/*设置状态,PTHREAD_CANCEL_ENABLE是正常处理cancel信号*/ while(1){sem_wait(&producer_semaphore);/*等待,需要生存*/srand((int)time(NULL)*(int)tid);sleep(rand()%2+1);/*一个或两个需要生产*/while((produce_pointer+1)%20==consume_pointer);/*指针位置*/sem_wait(&buffer_mutex);/*缓存区*/buffer[produce_pointer]=rand()%20+1;/*指针位置*/produce_pointer=(produce_pointer+1)%20;/*指针位置*//*判断*/if(produce_pointer==0){printf("生产者:%d指针指向:%2d生产产品号:%2d\n",(int)tid,19,buffer[19]);/*输出生产者,指针,缓存区*/fprintf(fd,"生产者:%d指针指向:%2d生产产品号:%2d\n",(int)tid,19,buffer[19]);/*输出生产者,指针,缓存区*/}else{printf("生产者:%d指针指向:%2d生产产品号:%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);/*输出生产者,指针,缓存区*/fprintf(fd,"生产者:%d指针指向:%2d生产产品号:%2d\n",(int)tid,produce_pointer-1,buffer[produce_pointer-1]);/*输出生产者,指针,缓存区*/}showbuf();sem_post(&buffer_mutex);sem_post(&consumer_semaphore);/*通知消费者缓冲区不是空的*/srand((int)time(NULL)*(int)tid);sleep(rand()%5+1);/*等待几秒钟,然后继续生产*/}return((void*)0);}void*consumer_thread(void*tid){/*可以被其他线程使用*/pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);/*设置状态,PTHREAD_CANCEL_ENABLE是忽略cancel信号*/while(1){sem_wait(&consumer_semaphore);/*通知消费者消费*/srand((int)time(NULL)*(int)tid);sleep(rand()%2+1);/*一个或两个来消费*/sem_wait(&buffer_mutex);printf("消费者:%d指针指向:%2d消费产品号:%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);/*输出消费者,消费者指针,缓存区*/fprintf(fd,"消费者:%d指针指向:%2d消费产品号:%2d\n",(int)tid,consume_pointer,buffer[consume_pointer]);/*输出消费者,消费者指针,缓存区*/buffer[consume_pointer]=0;/*消费者指针指向0*/consume_pointer=(consume_pointer+1)%20;showbuf();sem_post(&buffer_mutex);sem_post(&producer_semaphore);/*通知生产者缓冲区不是空的*/srand((int)time(NULL)*(int)tid);sleep(rand()%5+1);/*等待几秒钟,然后继续消费*/}return((void*)0);}/*查看缓冲区内容*/void showbuf(){int i;/*定义i*/printf("buffer:");/*输出缓存区*/fprintf(fd,"buffer:");/*输出缓存区*/for(i=0;i<MAX_BUFFER;i++){printf("%2d",buffer[i]);/*输出缓存区i*/fprintf(fd,"%2d",buffer[i]);/*输出缓存区i*/ }printf("\n\n");/*换行*/fprintf(fd,"\n\n");/*换行*/}。

kafka生产者和消费者的javaAPI的示例代码

kafka生产者和消费者的javaAPI的示例代码

kafka⽣产者和消费者的javaAPI的⽰例代码写了个kafka的java demo 顺便记录下,仅供参考1.创建maven项⽬⽬录如下:2.pom⽂件:<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>Kafka-Maven</groupId><artifactId>Kafka-Maven</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka_2.11</artifactId><version>0.10.1.1</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.2.0</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>1.0.3</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>1.0.3</version></dependency><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-hdfs</artifactId><version>2.2.0</version></dependency><dependency><groupId>jdk.tools</groupId><artifactId>jdk.tools</artifactId><version>1.7</version><scope>system</scope><systemPath>${JAVA_HOME}/lib/tools.jar</systemPath></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.3.6</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build></project>3.kafka⽣产者KafkaProduce:package com.lijie.producer;import java.io.File;import java.io.FileInputStream;import java.util.Properties;import org.apache.kafka.clients.producer.Callback;import org.apache.kafka.clients.producer.KafkaProducer;import org.apache.kafka.clients.producer.ProducerRecord;import org.apache.kafka.clients.producer.RecordMetadata;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class KafkaProduce {private static Properties properties;static {properties = new Properties();String path = KafkaProducer.class.getResource("/").getFile().toString()+ "kafka.properties";try {FileInputStream fis = new FileInputStream(new File(path));properties.load(fis);} catch (Exception e) {e.printStackTrace();}}/*** 发送消息** @param topic* @param key* @param value*/public void sendMsg(String topic, byte[] key, byte[] value) {// 实例化produceKafkaProducer<byte[], byte[]> kp = new KafkaProducer<byte[], byte[]>( properties);// 消息封装ProducerRecord<byte[], byte[]> pr = new ProducerRecord<byte[], byte[]>( topic, key, value);// 发送数据kp.send(pr, new Callback() {// 回调函数@Overridepublic void onCompletion(RecordMetadata metadata,Exception exception) {if (null != exception) {System.out.println("记录的offset在:" + metadata.offset());System.out.println(exception.getMessage() + exception);}}});// 关闭producekp.close();}}4.kafka消费者KafkaConsume:package com.lijie.consumer;import java.io.File;import java.io.FileInputStream;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Properties;import org.apache.htrace.fasterxml.jackson.databind.ObjectMapper;import er;import com.lijie.utils.JsonUtils;import kafka.consumer.ConsumerConfig;import kafka.consumer.ConsumerIterator;import kafka.consumer.KafkaStream;import kafka.javaapi.consumer.ConsumerConnector;import kafka.serializer.StringDecoder;import kafka.utils.VerifiableProperties;public class KafkaConsume {private final static String TOPIC = "lijietest";private static Properties properties;static {properties = new Properties();String path = KafkaConsume.class.getResource("/").getFile().toString()+ "kafka.properties";try {FileInputStream fis = new FileInputStream(new File(path));properties.load(fis);} catch (Exception e) {e.printStackTrace();}}/*** 获取消息** @throws Exception*/public void getMsg() throws Exception {ConsumerConfig config = new ConsumerConfig(properties);ConsumerConnector consumer = kafka.consumer.Consumer.createJavaConsumerConnector(config);Map<String, Integer> topicCountMap = new HashMap<String, Integer>();topicCountMap.put(TOPIC, new Integer(1));StringDecoder keyDecoder = new StringDecoder(new VerifiableProperties()); StringDecoder valueDecoder = new StringDecoder(new VerifiableProperties());Map<String, List<KafkaStream<String, String>>> consumerMap = consumer .createMessageStreams(topicCountMap, keyDecoder, valueDecoder);KafkaStream<String, String> stream = consumerMap.get(TOPIC).get(0);ConsumerIterator<String, String> it = stream.iterator();while (it.hasNext()) {String json = it.next().message();User user = (User) JsonUtils.JsonToObj(json, User.class);System.out.println(user);}}}5.kafka.properties⽂件##producebootstrap.servers=192.168.80.123:9092producer.type=syncrequest.required.acks=1serializer.class=kafka.serializer.DefaultEncoderkey.serializer=mon.serialization.ByteArraySerializervalue.serializer=mon.serialization.ByteArraySerializerbak.partitioner.class=kafka.producer.DefaultPartitionerbak.key.serializer=mon.serialization.StringSerializerbak.value.serializer=mon.serialization.StringSerializer##consumezookeeper.connect=192.168.80.123:2181group.id=lijiegroupzookeeper.session.timeout.ms=4000zookeeper.sync.time.ms=200mit.interval.ms=1000auto.offset.reset=smallestserializer.class=kafka.serializer.StringEncoder以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

操作系统生产者消费者代码c++语言

操作系统生产者消费者代码c++语言

操作系统生产者消费者代码c++语言操作系统是计算机系统中极为重要的一个组成部分,它负责管理计算机硬件和软件资源,为用户和应用程序提供高效的运行环境。

生产者消费者问题是操作系统中经典的一个并发控制问题,它涉及到多个线程之间的合作与协调。

生产者消费者问题的场景通常是一个缓冲区(也可以称为仓库)和两类线程,即生产者线程和消费者线程。

生产者线程负责向缓冲区中生产产品,而消费者线程则负责从缓冲区中消费产品。

这两类线程必须互相合作,保证生产者线程不会在缓冲区已满时继续生产,消费者线程不会在缓冲区为空时继续消费,以避免数据不一致性的问题。

解决生产者消费者问题的常用方法是使用互斥锁和条件变量。

互斥锁(Mutex)用于保护对缓冲区的访问,当某个线程希望访问缓冲区时,需要先获取互斥锁,其他线程必须等待该线程释放锁后才能进行访问。

条件变量(Condition Variable)用于实现线程间的信号通知机制,当某个线程生产了一个产品并将其放入缓冲区后,需要通知消费者线程可以开始消费了,而当消费者线程消费完一个产品后,需要通知生产者线程可以继续生产。

下面是一个简单的C++代码示例:```cppinclude<iostream>include<queue>include<pthread.h>using namespace std;queue<int>buffer;pthread_mutex_t mutex;pthread_cond_t full_cond,empty_cond;void*producer(void*arg){while(true){pthread_mutex_lock(&mutex);while(buffer.size()>=10){pthread_cond_wait(&full_cond,&mutex);}int product=rand()%100;buffer.push(product);cout<<"Producer produced:"<<product<<endl;pthread_cond_signal(&empty_cond);pthread_mutex_unlock(&mutex);usleep(100000);}}void*consumer(void*arg){while(true){pthread_mutex_lock(&mutex);while(buffer.empty()){pthread_cond_wait(&empty_cond,&mutex);}int product=buffer.front();buffer.pop();cout<<"Consumer consumed:"<<product<<endl;pthread_cond_signal(&full_cond);pthread_mutex_unlock(&mutex);usleep(200000);}}int main(){pthread_t producer_thread,consumer_thread;pthread_mutex_init(&mutex,NULL);pthread_cond_init(&full_cond,NULL);pthread_cond_init(&empty_cond,NULL);pthread_create(&producer_thread,NULL,producer, NULL);pthread_create(&consumer_thread,NULL,consumer, NULL);pthread_join(producer_thread,NULL);pthread_join(consumer_thread,NULL);pthread_mutex_destroy(&mutex);pthread_cond_destroy(&full_cond);pthread_cond_destroy(&empty_cond);return0;}```在这个例子中,我们使用了一个全局的`buffer`队列作为缓冲区,使用`pthread_mutex_t`类型的变量`mutex`来保护对缓冲区的访问,使用`pthread_cond_t`类型的变量`full_cond`和`empty_cond`来实现线程间的通信。

C语言实现多个生产者和消费者

C语言实现多个生产者和消费者

C语言实现多个生产者和消费者#include "windows.h"#include "conio.h"#include "stdio.h"#define NUM 10 //缓冲区的数量#define PRO 5 //生产者的数量#define CON 3 //消费者的数量int a[NUM]; //循环缓冲区int count=1; //计数值初始化static HANDLE full; //全局满缓冲区信号量的声明static HANDLE empty; //全局空缓冲区信号量的声明 HANDLE mutex; //全局互斥信号量的声明void Proclucer(){while(1){if(count>=NUM){printf("缓冲区已满,请等待3秒~\n");Sleep(3000);}else{int product=4; //初始化产品WaitForSingleObject(empty,INFINITE); //p操作,判断缓冲区是否为满WaitForSingleObject(mutex,INFINITE); //互斥p操作count=count%NUM;a[count]=product;count++;printf("生产者生产产品总数为:%d\n",count); //向缓冲区放入产品Sleep(3000);ReleaseMutex(mutex); //释放互斥信号量ReleaseSemaphore(empty,1,NULL); //释放自然信号量}}}void Consumer(){while(1){if(count<=0){printf("缓冲区已空,请等待3秒~\n");Sleep(3000);}else{int consumer=0; //初始化消费变量WaitForSingleObject(empty,INFINITE); //pc操作,判断缓冲区是否为满WaitForSingleObject(mutex,INFINITE); //互斥p操作count=count%NUM;consumer=a[count];count--;printf("消费者消费产品总数为:%d\n",count); //向缓冲区取出产品Sleep(3000);ReleaseMutex(mutex); //释放互斥信号量ReleaseSemaphore(empty,1,NULL); //释放自然信号量}}}HANDLE pThread[PRO]; //生产者进程句柄HANDLE cThread[CON]; //消费者进程句柄HANDLE oThread; //生产者进程句柄int opration(){int a=getchar();return a;}void Start(){int i;for(i=0;i<PRO;i++){pThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Proclucer,NUL L,0,NULL);//创建生产者线程}for(i=0;i<CON;i++){cThread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Consumer,NULL ,0,NULL);//创建消费者线程}oThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)opration,NULL,0, NULL);int isopration=opration();if(isopration==0){for(i=0;i<PRO;i++){CloseHandle(pThread[i]);}for(i=0;i<PRO;i++){CloseHandle(cThread[i]);}CloseHandle(oThread);}oThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)opration,NULL,0, NULL);//结束操作线程mutex=CreateMutex(NULL,FALSE,"mutex1"); //创建互斥信号量full=CreateSemaphore(NULL,0,NUM,"emptyHandle"); //创建满缓冲区信号量,初始化为0;empty=CreateSemaphore(NULL,NUM,NUM,"emptyHandle"); //创建空缓冲区信号量,初始化为10;}void main(){Start();printf("/n");}。

生产者和消费者代码

生产者和消费者代码

#include<windows.h>#include<fstream.h>#include<stdio.h>#include<string>#include<conio.h>//定义一些常量;//本程序允许的最大临界区数;#define MAX_BUFFER_NUM 10//秒到微秒的乘法因子;#define INTE_PER_SEC 1000//本程序允许的生产和消费线程的总数;#define MAX_THREAD_NUM 64//定义一个结构,记录在测试文件中指定的每一个线程的参数struct ThreadInfo{int serial; //线程序列号char entity; //是P还是Cdouble delay; //线程延迟int thread_request[MAX_THREAD_NUM]; //线程请求队列int n_request; //请求个数};//全局变量的定义//临界区对象的声明,用于管理缓冲区的互斥访问;int Buffer_Critical[MAX_BUFFER_NUM]; //缓冲区声明,用于存放产品;ThreadInfo Thread_Info[MAX_THREAD_NUM]; //线程信息数组;HANDLE h_Thread[MAX_THREAD_NUM]; //用于存储每个线程句柄的数组;HANDLE empty_semaphore; //一个信号量;HANDLE h_mutex; //一个互斥量;HANDLE h_Semaphore[MAX_THREAD_NUM]; //生产者允许消费者开始消费的信号量;CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];DWORD n_Thread = 0; //实际的线程的数目;DWORD n_Buffer_or_Critical; //实际的缓冲区或者临界区的数目;//生产消费及辅助函数的声明void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(int);int FindProducePositon();int FindBufferPosition(int);int main(int argc, char **argv){//声明所需变量;DWORD wait_for_all;ifstream inFile;if (argc!=2) {printf("Usage:%s <File>\n",argv[0]);return 1;}//初始化缓冲区;for(int i=0;i< MAX_BUFFER_NUM;i++)Buffer_Critical[i] = -1;//初始化每个线程的请求队列;for(int j=0;j<MAX_THREAD_NUM;j++) {for(int k=0;k<MAX_THREAD_NUM;k++)Thread_Info[j].thread_request[k] = -1;Thread_Info[j].n_request = 0;}//初始化临界区;for(i =0;i< MAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]);//打开输入文件,按照规定的格式提取线程等信息;inFile.open(argv[1]);//从文件中获得实际的缓冲区的数目,即测试文件第一行的信息;inFile >> n_Buffer_or_Critical;inFile.get(); // 读取测试文件中的空格,将文件指针指向下一行;printf("输入文件是:\n");//回显获得的缓冲区的数目信息;printf("%d \n",(int) n_Buffer_or_Critical);//提取每个线程的信息到相应数据结构中;while(inFile){inFile >> Thread_Info[n_Thread].serial;inFile >> Thread_Info[n_Thread].entity;inFile >> Thread_Info[n_Thread].delay;char c;inFile.get(c);while(c!='\n'&& !inFile.eof()) {inFile>> Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];inFile.get(c);}n_Thread++;}//回显获得的线程信息,便于确认正确性;for(j=0;j<(int) n_Thread;j++) {int Temp_serial = Thread_Info[j].serial;char Temp_entity = Thread_Info[j].entity;double Temp_delay = Thread_Info[j].delay;printf(" \nthread%2d %c %f ",Temp_serial,Temp_entity,Temp_delay);int Temp_request = Thread_Info[j].n_request;for(int k=0;k<Temp_request;k++)printf(" %d ", Thread_Info[j].thread_request[k]);cout<<endl;}printf("\n\n");//创建在模拟过程中几个必要的信号量empty_semaphore = CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical, "semaphore_for_empty");h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update");//下面这个循环用线程的ID号来为相应生产线程的产品读写时所//使用的同步信号量命名;for(j=0;j<(int)n_Thread;j++) {char lp[]="semaphore_for_produce_";int temp =j;while(temp){char c = (char)(temp%10);strcat(lp,&c);temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp);}//创建生产者和消费者线程;for(i =0;i< (int) n_Thread;i++) {if(Thread_Info[i].entity =='P')h_Thread[i]= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Info[i]),0,NULL);}//主程序等待各个线程的动作结束;wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf(" \n \nALL Producer and consumer have finished their work. \n");printf("Press any key to quit!\n");_getch();return 0;}//确认是否还有对同一产品的消费请求未执行;bool IfInOtherRequest(int req){for(int i=0;i<n_Thread;i++)for(int j=0;j<Thread_Info[i].n_request;j++)if(Thread_Info[i].thread_request[j] == req)return TRUE;return FALSE;}//找出当前可以进行产品生产的空缓冲区位置;int FindProducePosition(){int EmptyPosition;for (int i =0;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i] == -1) {EmptyPosition = i;//用下面这个特殊值表示本缓冲区正处于被写状态;Buffer_Critical[i] = -2;break;}return EmptyPosition;}//找出当前所需生产者生产的产品的位置;int FindBufferPosition(int ProPos){int TempPos;for (int i =0 ;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i]==ProPos){TempPos = i;break;}return TempPos;}//生产者进程void Produce(void *p){//局部变量声明;DWORD wait_for_semaphore,wait_for_mutex,m_delay;int m_serial;//获得本线程的信息;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);Sleep(m_delay);//开始请求生产printf("Producer %2d sends the produce require.\n",m_serial);//互斥访问下一个可用于生产的空临界区,实现写写互斥;wait_for_mutex = WaitForSingleObject(h_mutex,-1);//确认有空缓冲区可供生产,同时将空位置数empty减1;用于生产者和消费者的同步;//若没有则一直等待,直到消费者进程释放资源为止;wait_for_semaphore = WaitForSingleObject(empty_semaphore,-1);int ProducePos = FindProducePosition();ReleaseMutex(h_mutex);//生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发;//核心生产步骤中,程序将生产者的ID作为产品编号放入,方便消费者识别;printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos);Buffer_Critical[ProducePos] = m_serial;printf("Producer %2d finish producing :\n ",m_serial);printf(" position[ %2d ]:%3d \n\n" ,ProducePos,Buffer_Critical[ProducePos]);//使生产者写的缓冲区可以被多个消费者使用,实现读写同步;ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);}//消费者进程void Consume(void * p){//局部变量声明;DWORD wait_for_semaphore,m_delay;int m_serial,m_requestNum; //消费者的序列号和请求的数目;int m_thread_request[MAX_THREAD_NUM]; //本消费线程的请求队列;//提取本线程的信息到本地;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_requestNum = ((ThreadInfo *)(p))->n_request;for (int i = 0;i<m_requestNum;i++)m_thread_request[i] = ((ThreadInfo*)(p))->thread_request[i];Sleep(m_delay);//循环进行所需产品的消费for(i =0;i<m_requestNum;i++){//请求消费下一个产品printf("Consumer %2d request to consume %2d product\n",m_serial,m_thread_request[i]);//如果对应生产者没有生产,则等待;如果生产了,允许的消费者数目-1;实现了读写同步;wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);//查询所需产品放到缓冲区的号int BufferPos=FindBufferPosition(m_thread_request[i]);//开始进行具体缓冲区的消费处理,读和读在该缓冲区上仍然是互斥的;//进入临界区后执行消费动作;并在完成此次请求后,通知另外的消费者本处请求已//经满足;同时如果对应的产品使用完毕,就做相应处理;并给出相应动作的界面提//示;该相应处理指将相应缓冲区清空,并增加代表空缓冲区的信号量;EnterCriticalSection(&PC_Critical[BufferPos]);printf("Consumer %2d begin to consume %2d product \n",m_serial,m_thread_request[i]);((ThreadInfo*)(p))->thread_request[i] =-1;if(!IfInOtherRequest(m_thread_request[i])) {Buffer_Critical[BufferPos] = -1; //-1标记缓冲区为空;printf("Consumer %2d finish consuming %2d:\n ",m_serial,m_thread_request[i]);printf(" position[ %2d ]:%3d \n\n" ,BufferPos,Buffer_Critical[BufferPos]);ReleaseSemaphore(empty_semaphore,1,NULL);}else {printf("Consumer %2d finish consuming product %2d\n\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}。

生产者和消费者模式-代码

生产者和消费者模式-代码

⽣产者和消费者模式-代码函数:⽣产者和消费者import randomfrom queue import Queuefrom threading import Thread, current_threadimport time# 实例化⼀个队列myq = Queue()# 定义⽣产者def producer():while True:tmp = random.randint(1,100)myq.put(tmp)print("%s⽣产了%s,⽣产后,现在产品总量:%s" % (current_thread().name, tmp, myq.qsize()))time.sleep(0.5)# 定义消费者def consumer():while True:print("%s消费了%s,剩余产品%s" % (current_thread().name, myq.get(), myq.qsize()))time.sleep(1.1)# 启动⽣产者和消费者# 启动⽣产者tp = Thread(target=producer)tp.start()# 启动消费者for i in range(2):tc = Thread(target=consumer)tc.start()函数2:# 编写⼀个基于tcp的echo服务器(回响服务器,即将客户端发送的信息返回给客户端),# 要求使⽤线程和⽣产者消费者模型(提⽰:⼀个线程accept--⽣产者;两个线程⽤于接收和发送--消费者)。

import socketfrom threading import Thread, current_threadfrom queue import Queue# ⽣产者def accept_t(queue):print("当前线程",current_thread().name)# client_info = server.accept()# queue.put(client_info)# 消费者recvdef recv_t(queue, queue_data):client_info = queue.get()client_sock = client_info[0]data = client_sock.recv(1024)queue_data.put(data)passtry:print(data.decode())except:print(data.decode('gbk'))# 消费者senddef send_t(queue_data):data = queue_data.get()client_sock = client_info[0]client_sock.send(data)client_sock.close()passif __name__ == "__main__":client_info = Noneserver = None# 创建服务器的套接字(监听套接字)server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置地址复⽤属性server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 绑定IP和端⼝server_address = ("", 7972)server.bind(server_address)# 监听server.listen(128)queue = Queue()queue_data = Queue()t1 = Thread(target=accept_t, args=(queue))t1.start()t2 = Thread(target=recv_t, args=(queue, queue_data))t2.start()t3 = Thread(target=send_t, args=(queue_data,))t3.start()t1.join()t2.join()t3.join()类:⽣产者和消费者import socketfrom queue import Queuefrom threading import Threadimport timeimport chardetclient_queue = Queue()# ⽣产者class Producer(Thread):def __init__(self, tcp_server):super().__init__()self.tcp_server = tcp_serverdef run(self):client_info = self.tcp_server.accept()client_queue.put(client_info)# 消费者class Consumer(Thread):def __init__(self):super().__init__()def run(self):client_info = client_queue.get()client_sock = client_info[0]client_addr = client_info[1]msg = client_sock.recv(1024)print("原始字节流:",msg)a = 'abcd'.encode("UTF-8")print('a:', a)# a = msg.decode()code = chardet.detect(a)print('获取到a的编码是',code['encoding'])print("%s说:%s" % (client_addr, msg.decode()))client_sock.send(msg.decode().encode('gbk'))client_sock.close()print('consumer is over')# 主函数def main():tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) tcp_server.bind(("", 7892))tcp_server.listen(128)p = Producer(tcp_server)c1 = Consumer()# c2 = Consumer()p.start()c1.start()# c2.start()# time.sleep(2)p.join()c1.join()# c2.join()tcp_server.close()if __name__ == '__main__':main()。

生产者消费者程序代码

生产者消费者程序代码

生产者消费者代码import java.util.concurrent.*;import java.util.concurrent.locks.*;public class ConsumerProducer {private static Buffer buffer = new Buffer();public static void main(String[] args) {// Create a thread pool with two threadsExecutorService executor = Executors.newFixedThreadPool(2);executor.execute(new ProducerTask());executor.execute(new ConsumerTask());executor.shutdown();}// A task for adding an int to the bufferprivate static class ProducerTask implements Runnable {public void run() {try {int i = 1;while (true) {System.out.println("Producer writes " + i);buffer.write(i++); // Add a value to the buffer// Put the thread into sleepThread.sleep((int)(Math.random() * 10000));}} catch (InterruptedException ex) {ex.printStackTrace();}}}// A task for reading and deleting an int from the bufferprivate static class ConsumerTask implements Runnable {public void run() {try {while (true) {System.out.println("\t\t\tConsumer reads " + buffer.read());// Put the thread into sleepThread.sleep((int)(Math.random() * 10000));}} catch (InterruptedException ex) {ex.printStackTrace();}}}// An inner class for bufferprivate static class Buffer {private static final int CAPACITY = 1; // buffer sizeprivate java.util.LinkedList<Integer> queue =new java.util.LinkedList<Integer>();// Create a new lockprivate static Lock lock = new ReentrantLock();// Create two conditionsprivate static Condition notEmpty = lock.newCondition();private static Condition notFull = lock.newCondition();public void write(int value) {lock.lock(); // Acquire the locktry {while (queue.size() == CAPACITY) {System.out.println("Wait for notFull condition");notFull.await();}queue.offer(value);notEmpty.signal(); // Signal notEmpty condition} catch (InterruptedException ex) {ex.printStackTrace();} finally {lock.unlock(); // Release the lock}}public int read() {int value = 0;lock.lock(); // Acquire the locktry {while (queue.isEmpty()) {System.out.println("\t\t\tWait for notEmpty condition");notEmpty.await();}value = queue.remove();notFull.signal(); // Signal notFull condition} catch (InterruptedException ex) {ex.printStackTrace();} finally {lock.unlock(); // Release the lockreturn value;}}}}。

java生产者消费者模式代码示例

java生产者消费者模式代码示例

java⽣产者消费者模式代码⽰例package test;import java.util.LinkedList;public class Test {public static void main(String[] args) {R r = new R();P p1 = new P(r,10);P p2 = new P(r,20);P p3 = new P(r,30);P p4 = new P(r,40);P p5 = new P(r,50);C c1 = new C(r,10);C c2 = new C(r,20);C c3 = new C(r,30);C c4 = new C(r,40);C c5 = new C(r,50);new Thread(p1).start();new Thread(c1).start();new Thread(p2).start();new Thread(c2).start();new Thread(p3).start();new Thread(c3).start();new Thread(p4).start();new Thread(c4).start();new Thread(p5).start();new Thread(c5).start();}}class P implements Runnable{private R r;private int n;public P(R _r,int _n){this.r = _r;this.n = _n;}@Overridepublic void run() {r.push(n);}}class C implements Runnable{private R r;private int n;public C(R _r,int _n){this.r = _r;this.n = _n;}@Overridepublic void run() {r.pop(n);}}class R {private LinkedList<Object> c = new LinkedList<Object>();private static final int MAX_SIZE = 100;public void push(int n){synchronized (c) {if(c.size()+n <= MAX_SIZE){for(int i=0;i<n;i++){c.add(new Object());}System.out.println("⽣产者:⽣产了"+n+"个产品,现在⼀共有"+c.size()+"个产品,并唤醒消费者线程控可以消费了");c.notifyAll();}else{System.out.println("⽣产者:要⽣产的产品个数:"+n+",⼤于仓库剩余空间"+(MAX_SIZE-c.size())+"当前⽣产者线程进⼊等待状态。

操作系统生产者消费者问题代码

操作系统生产者消费者问题代码

#include <windows.h>#include <fstream.h>#include <iostream.h>#include <string>#include <conio.h>//声明所需变量int in=0;int out=0;HANDLE h_Thread[20]; //线程数组HANDLE empty_Semaphore; //表示空缓冲区的信号量HANDLE full_Semaphore; //表示空缓冲区的信号量HANDLE mutex;struct data{int ID;//序号char type;//类型,是生产者还是消费者,p or cdouble delay;//线程延迟的时间,对应生产者生产产品的时间或消费者消费产品的时间};data ThreadInfo[20]; //线程信息数组int length; //线程信息数组中实际的线程个数void Produce(void *p);//生产者进程void Consume(void *p);//消费者进程void input(void);int main(void){input();//初始化临界区对象//InitializeCriticalSection(&PC_Critical);empty_Semaphore=CreateSemaphore(NULL,10,10,NULL);full_Semaphore=CreateSemaphore(NULL,0,10,NULL);mutex = ::CreateMutex(NULL,FALSE,NULL);cout<<"下面生产者和消费者开始工作!!"<<endl;cout<<endl;//创建生产者和消费者线程for(int i=0;i<length;i++){if(ThreadInfo[i].type=='p')h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(ThreadInfo[i]), 0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(ThreadInfo[i]),0,N ULL);}//主程序等待各个线程的动作结束WaitForMultipleObjects(length,h_Thread,TRUE,-1);cout<<endl;::Sleep(1000000);cout<<"所有的生产者和消费者都完成了它们的工作!!"<<endl<<endl;return 0;}//***************************************************************************** ************//生产者进程//***************************************************************************** *************void Produce(void *p){}//***************************************************************************** ************//消费者进程//***************************************************************************** *************void Consume(void *p){//局部变量声明int my_id;double my_delay;//从线程信息数组中获得信息my_id =((data*)(p))->ID;my_delay=((data*)(p))->delay;//开始请求xiaofeicout<<"消费者"<<my_id<<"发出消费请求。

四、RocketMq简单的消费者和生产者(示例代码)

四、RocketMq简单的消费者和生产者(示例代码)

四、RocketMq简单的消费者和⽣产者(⽰例代码)⼀、⽣产者 使⽤RocketMQ以三种⽅式发送消息:可靠的同步,可靠的异步和单向传输。

(1)同步发送消息(可靠的同步传输,适⽤于重要的短信通知等)public class SyncProducer {public static void main(String[] args) throws Exception {//Instantiate with a producer group name.DefaultMQProducer producer = newDefaultMQProducer("please_rename_unique_group_name");// Specify name server addresses.producer.setNamesrvAddr("localhost:9876");//Launch the instance.producer.start();for (int i = 0; i < 100; i++) {//Create a message instance, specifying topic, tag and message body.Message msg = new Message("TopicTest" /* Topic */,"TagA" /* Tag */,("Hello RocketMQ " +i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */);//Call send message to deliver message to one of brokers.SendResult sendResult = producer.send(msg);System.out.printf("%s%n", sendResult);}//Shut down once the producer instance is not longer in use.producer.shutdown();}} (2)异步传输通常⽤于响应时间敏感的业务场景。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<windows.h>#include<fstream.h>#include<stdio.h>#include<string>#include<conio.h>//定义一些常量;//本程序允许的最大临界区数;#define MAX_BUFFER_NUM 10//秒到微秒的乘法因子;#define INTE_PER_SEC 1000//本程序允许的生产和消费线程的总数;#define MAX_THREAD_NUM 64//定义一个结构,记录在测试文件中指定的每一个线程的参数struct ThreadInfo{int serial; //线程序列号char entity; //是P还是Cdouble delay; //线程延迟int thread_request[MAX_THREAD_NUM]; //线程请求队列int n_request; //请求个数};//全局变量的定义//临界区对象的声明,用于管理缓冲区的互斥访问;int Buffer_Critical[MAX_BUFFER_NUM]; //缓冲区声明,用于存放产品;ThreadInfo Thread_Info[MAX_THREAD_NUM]; //线程信息数组;HANDLE h_Thread[MAX_THREAD_NUM]; //用于存储每个线程句柄的数组;HANDLE empty_semaphore; //一个信号量;HANDLE h_mutex; //一个互斥量;HANDLE h_Semaphore[MAX_THREAD_NUM]; //生产者允许消费者开始消费的信号量;CRITICAL_SECTION PC_Critical[MAX_BUFFER_NUM];DWORD n_Thread = 0; //实际的线程的数目;DWORD n_Buffer_or_Critical; //实际的缓冲区或者临界区的数目;//生产消费及辅助函数的声明void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(int);int FindProducePositon();int FindBufferPosition(int);int main(int argc, char **argv){//声明所需变量;DWORD wait_for_all;ifstream inFile;if (argc!=2) {printf("Usage:%s <File>\n",argv[0]);return 1;}//初始化缓冲区;for(int i=0;i< MAX_BUFFER_NUM;i++)Buffer_Critical[i] = -1;//初始化每个线程的请求队列;for(int j=0;j<MAX_THREAD_NUM;j++) {for(int k=0;k<MAX_THREAD_NUM;k++)Thread_Info[j].thread_request[k] = -1;Thread_Info[j].n_request = 0;}//初始化临界区;for(i =0;i< MAX_BUFFER_NUM;i++)InitializeCriticalSection(&PC_Critical[i]);//打开输入文件,按照规定的格式提取线程等信息;inFile.open(argv[1]);//从文件中获得实际的缓冲区的数目,即测试文件第一行的信息;inFile >> n_Buffer_or_Critical;inFile.get(); // 读取测试文件中的空格,将文件指针指向下一行;printf("输入文件是:\n");//回显获得的缓冲区的数目信息;printf("%d \n",(int) n_Buffer_or_Critical);//提取每个线程的信息到相应数据结构中;while(inFile){inFile >> Thread_Info[n_Thread].serial;inFile >> Thread_Info[n_Thread].entity;inFile >> Thread_Info[n_Thread].delay;char c;inFile.get(c);while(c!='\n'&& !inFile.eof()) {inFile>> Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];inFile.get(c);}n_Thread++;}//回显获得的线程信息,便于确认正确性;for(j=0;j<(int) n_Thread;j++) {int Temp_serial = Thread_Info[j].serial;char Temp_entity = Thread_Info[j].entity;double Temp_delay = Thread_Info[j].delay;printf(" \nthread%2d %c %f ",Temp_serial,Temp_entity,Temp_delay);int Temp_request = Thread_Info[j].n_request;for(int k=0;k<Temp_request;k++)printf(" %d ", Thread_Info[j].thread_request[k]);cout<<endl;}printf("\n\n");//创建在模拟过程中几个必要的信号量empty_semaphore = CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical, "semaphore_for_empty");h_mutex = CreateMutex(NULL,FALSE,"mutex_for_update");//下面这个循环用线程的ID号来为相应生产线程的产品读写时所//使用的同步信号量命名;for(j=0;j<(int)n_Thread;j++) {char lp[]="semaphore_for_produce_";int temp =j;while(temp){char c = (char)(temp%10);strcat(lp,&c);temp/=10;}h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,lp);}//创建生产者和消费者线程;for(i =0;i< (int) n_Thread;i++) {if(Thread_Info[i].entity =='P')h_Thread[i]= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Info[i]),0,NULL);elseh_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Info[i]),0,NULL);}//主程序等待各个线程的动作结束;wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf(" \n \nALL Producer and consumer have finished their work. \n");printf("Press any key to quit!\n");_getch();return 0;}//确认是否还有对同一产品的消费请求未执行;bool IfInOtherRequest(int req){for(int i=0;i<n_Thread;i++)for(int j=0;j<Thread_Info[i].n_request;j++)if(Thread_Info[i].thread_request[j] == req)return TRUE;return FALSE;}//找出当前可以进行产品生产的空缓冲区位置;int FindProducePosition(){int EmptyPosition;for (int i =0;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i] == -1) {EmptyPosition = i;//用下面这个特殊值表示本缓冲区正处于被写状态;Buffer_Critical[i] = -2;break;}return EmptyPosition;}//找出当前所需生产者生产的产品的位置;int FindBufferPosition(int ProPos){int TempPos;for (int i =0 ;i<n_Buffer_or_Critical;i++)if(Buffer_Critical[i]==ProPos){TempPos = i;break;}return TempPos;}//生产者进程void Produce(void *p){//局部变量声明;DWORD wait_for_semaphore,wait_for_mutex,m_delay;int m_serial;//获得本线程的信息;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);Sleep(m_delay);//开始请求生产printf("Producer %2d sends the produce require.\n",m_serial);//互斥访问下一个可用于生产的空临界区,实现写写互斥;wait_for_mutex = WaitForSingleObject(h_mutex,-1);//确认有空缓冲区可供生产,同时将空位置数empty减1;用于生产者和消费者的同步;//若没有则一直等待,直到消费者进程释放资源为止;wait_for_semaphore = WaitForSingleObject(empty_semaphore,-1);int ProducePos = FindProducePosition();ReleaseMutex(h_mutex);//生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发;//核心生产步骤中,程序将生产者的ID作为产品编号放入,方便消费者识别;printf("Producer %2d begin to produce at position %2d.\n",m_serial,ProducePos);Buffer_Critical[ProducePos] = m_serial;printf("Producer %2d finish producing :\n ",m_serial);printf(" position[ %2d ]:%3d \n\n" ,ProducePos,Buffer_Critical[ProducePos]);//使生产者写的缓冲区可以被多个消费者使用,实现读写同步;ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);}//消费者进程void Consume(void * p){//局部变量声明;DWORD wait_for_semaphore,m_delay;int m_serial,m_requestNum; //消费者的序列号和请求的数目;int m_thread_request[MAX_THREAD_NUM]; //本消费线程的请求队列;//提取本线程的信息到本地;m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay *INTE_PER_SEC);m_requestNum = ((ThreadInfo *)(p))->n_request;for (int i = 0;i<m_requestNum;i++)m_thread_request[i] = ((ThreadInfo*)(p))->thread_request[i];Sleep(m_delay);//循环进行所需产品的消费for(i =0;i<m_requestNum;i++){//请求消费下一个产品printf("Consumer %2d request to consume %2d product\n",m_serial,m_thread_request[i]);//如果对应生产者没有生产,则等待;如果生产了,允许的消费者数目-1;实现了读写同步;wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);//查询所需产品放到缓冲区的号int BufferPos=FindBufferPosition(m_thread_request[i]);//开始进行具体缓冲区的消费处理,读和读在该缓冲区上仍然是互斥的;//进入临界区后执行消费动作;并在完成此次请求后,通知另外的消费者本处请求已//经满足;同时如果对应的产品使用完毕,就做相应处理;并给出相应动作的界面提//示;该相应处理指将相应缓冲区清空,并增加代表空缓冲区的信号量;EnterCriticalSection(&PC_Critical[BufferPos]);printf("Consumer %2d begin to consume %2d product \n",m_serial,m_thread_request[i]);((ThreadInfo*)(p))->thread_request[i] =-1;if(!IfInOtherRequest(m_thread_request[i])) {Buffer_Critical[BufferPos] = -1; //-1标记缓冲区为空;printf("Consumer %2d finish consuming %2d:\n ",m_serial,m_thread_request[i]);printf(" position[ %2d ]:%3d \n\n" ,BufferPos,Buffer_Critical[BufferPos]);ReleaseSemaphore(empty_semaphore,1,NULL);}else {printf("Consumer %2d finish consuming product %2d\n\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}。

相关文档
最新文档