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() 等。如有需要解释这些函数,你等加加分哦,我就一一讲解。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)