编程题:用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_mutex

int main()

{

int i

int 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') break

return 0

}

void CQueue::addTail()

{

L.insert(L.end(),++GOODS_ID)

}

void CQueue::removeHead()

{

cout<<*L.begin()<<endl

L.erase(L.begin())

}

void ProducerThread(void* param)

{

int id = *(int*)param

while(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*)param

while(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() 等。如有需要解释这些函数,你等加加分哦,我就一一讲解。


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存