编程题:用c++实现生产者和消费者问题

编程题:用c++实现生产者和消费者问题,第1张

实现一个队列CQueue CQueue提供两个公有成员函数 addTail():往队列尾部增加一个元素 removeHead():读出并移除队列的第一个元素 生产者:两个线程通过调用CQueue::addTail()往队列中增加元素 消费者:一个线程通过调用CQueue::removeHead()从队列中读取元素 #include <iostream>#include <list>#include <windows.h>#include <process.h>using namespace std#define P(sem) WaitForSingleObject(sem,INFINITE) #define V(sem) ReleaseSemaphore(sem,1,NULL)class CQueue { public:void addTail()//往队列尾部增加一个元素void removeHead()//读出并移除队列的第一个元素 private:list<int>L}CQueue buffer//全局的缓冲区 const int buf_size = 10//缓冲区大小static int GOODS_ID = 0//商品序号const int producers = 3//生产者数量 const int consumers = 8//消费者数量void ProducerThread(void* param)void ConsumerThread(void* param)HANDLE empty,occupy,op_mutexint main() {int iint p_id[producers],c_id[consumers]occupy = CreateSemaphore(NULL,0,buf_size,NULL)//占用位置empty = CreateSemaphore(NULL,buf_size,buf_size,NULL)//空余位置op_mutex = CreateSemaphore(NULL,1,1,NULL)//操作互斥量for(i=0i<producers++i){p_id[i] = i+1_beginthread(ProducerThread,0,p_id+i)}for(i=0i<consumers++i){c_id[i] = i+1_beginthread(ConsumerThread,0,c_id+i)}while(getchar()=='\n') breakreturn 0}void CQueue::addTail() {L.insert(L.end(),++GOODS_ID)}void CQueue::removeHead() {cout<<*L.begin()<<endlL.erase(L.begin())}void ProducerThread(void* param) {int id = *(int*)paramwhile(1){P(empty)P(op_mutex)Sleep(100)buffer.addTail()printf("Producer_%d produced %d\n",id,GOODS_ID)V(op_mutex)V(occupy)} }void ConsumerThread(void* param) {int id = *(int*)paramwhile(1){P(occupy)P(op_mutex)Sleep(100)printf("Consumer_%d consumed ",id)buffer.removeHead()V(op_mutex)V(empty)} }

他把答案删除了,所以我也得改下了。

--------------------------

semop() 这是个信号函数。

系统调用:semop()

调用原型:int semop(int semid,struct sembuf*sops,unsign ednsops)

返回值:0,如果成功。-1,如果失败:errno=E2BIG(nsops大于最大的ops数目)

EACCESS(权限不够)

EAGAIN(使用了IPC_NOWAIT,但操作不能继续进行)

EFAULT(sops指向的地址无效)

EIDRM(信号量集已经删除)

EINTR(当睡眠时接收到其他信号)

EINVAL(信号量集不存在,或者semid无效)

ENOMEM(使用了SEM_UNDO,但无足够的内存创建所需的数据结构)

ERANGE(信号量值超出范围)

第一个参数是关键字值。第二个参数是指向将要操作的数组的指针。第三个参数是数组中的操作的个数。参数sops指向由sembuf组成的数组。此数组是在linux/sem.h中定义的:

/*semop systemcall takes an array of these*/

structsembuf{

ushortsem_num/*semaphore index in array*/

shortsem_op/*semaphore operation*/

shortsem_flg/*operation flags*/

sem_num将要处理的信号量的个数。

sem_op要执行的操作。

sem_flg操作标志。

如果sem_op是负数,那么信号量将减去它的值。这和信号量控制的资源有关。如果没有使用IPC_NOWAIT,那么调用进程将进入睡眠状态,直到信号量控制的资源可以使用为止。如果sem_op是正数,则信号量加上它的值。这也就是进程释放信号量控制的资源。最后,如果sem_op是0,那么调用进程将调用sleep(),直到信号量的值为0。这在一个进程等待完全空闲的资源时使用。

--------------------------

还比如: Semget(),semctl() 等。如有需要解释这些函数,你等加加分哦,我就一一讲解。

既然应用架构关注内容如此广泛,那么有没有统一的参考思路,用相对统一的表现形式去呈现不同应用系统的应用架构,避免五花八门的出品带来的沟通障碍和解释成本呢?

或许没有标准的方案,但是并不妨碍我们进行尝试。

根据系统的不同,应用架构中需要体现的业务区块、关联系统、领域对象和架构模式也会不同。但是如果我们通过抽象屏蔽掉具体的业务概念,通过从前到后的“三段式”拆解手法和按照关注进行区域归类手段,或许可以构建出高层次的应用架构模型,本文尝试介绍“三段三域法”。

所谓“三段”,是指一个对象可以根据处理时序、职责范围等内在逻辑进行抽象,分为三段,譬如前段的展示渠道、中段的处理核心、后段的资源支撑。三段式是一个通用概念,可以用在整个系统的维度,又可以用在放大后的系统局部部件中。

所谓“三域”,是指根据关注焦点、技术要求、指导思维和工具箱的不同,将系统从逻辑上拆分为业务域、数据域和技术域三者。业务域关注如何通过拆分组合的艺术手笔和多因素综合权衡的决策理念来完成整个系统的功能搭建;数据域则关注数据的集成汇聚、过滤萃取、利用算法等手段洞察客户意图和市场逻辑以及数据资产编目和服务于业务;技术域则从技术维度出发,聚焦可靠、安全、运维、管控等目标,尝试在各个信息交互的边界进行技术手段的植入。

打开APP查看高清大图

“三段三域法”应用架构模型图

首先,我们循着请求流向,来看“三段”。

在该模型中,我们我们假设每一个应用系统都有一个对外提供产品功能或服务能力的出口,我们称之为“数字化渠道”,它可以是面向内外不同群体的终端产品,譬如APP或者小程序,也可以是API,甚至是SDK。

其次是业务能力内核,包括请求接入、编排、持久化,是各类规则、流程、事务的集中营。

最后边的是支撑系统,可以是内部系统,也可以是外部系统,主要提供专业化的能力。

其次,从区域来看,每一个系统,基本都由业务、数据和技术三体组成(其实这也是另一个维度的“三段”)。

业务域关注是功能、流程、客户群体。又可以抽象划分为常规业务域,一般是企业的主营业务;创新业务域,一般是企业的增值类、开放式、生态类业务;支撑业务域,一般是偏向管控和支撑类的业务,譬如客服系统、工单系统等。最后一个可能出现的是共享业务域,涵盖各个类型业务的共享部分。每一个业务域之内的主体,我们统称为“部件”。

打开APP查看高清大图


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/498445.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-06-15
下一篇2023-06-15

发表评论

登录后才能评论

评论列表(0条)

    保存