用C语言实现--生产者与消费者的问题(PV操作)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用C语言实现--生产者与消费者的问题(PV操作)相关的知识,希望对你有一定的参考价值。

假定有一个生产者和消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。消费者每次从缓冲器内取出一件产品去消费。禁止生产者将产品放入已满的缓冲器内,禁止消费者从空缓冲器内取产品。假定缓冲器内可同时存放10件产品。那么,用PV操作来实现生产者和消费者之间的同步,生产者和消费者两个进程的程序如下:
B:array [0..9] of products;
s1,s2: semaphore;
IN, out; integer;
IN:=0;out:=0;
cobegin
procedure producer;
c: products;
begin
L1:
produce (c);
p (s1);
B[IN]:=C;
IN:=(IN+1)mod 10;
v(s2);
goto L1
end;
procedure consumer;
x: products;
begin
L2:P(s2);
x:=B[out];
out:=(out+1) mod 10;
v(s1);
consume(x);
goto L2
end;
coend

其中的semaphore和products是预先定义的两个类型,在模拟实现中semaphore用integer或char等代替

要求可以运行出结果才给分,没结果那就算了!

这个问题蛮好的
我给你个程序
给我加分啊
#include
<windows.h>
#include
<stdio.h>
#include
<stdlib.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
10
/*
消费者个数
*/
#define
PRODUCER_NUM
10
/*
生产者个数
*/
#define
BUFFER_NUM
4
/*
缓冲区个数
*/
char
*thing[10]
=
"猪脸",
"牛鞭",
"羊腰",
"驴蹄",
"狼心",
"狗肺",
"猴肝",
"老虎屁股",
"大象肚",
"河马大肠";
struct
Buffer

int
product[BUFFER_NUM];
//
缓冲区
int
start,
end;
//
两个指针

g_buf;
Semaphore
g_semBuffer,
g_semProduct,
g_mutex;
//
消费者线程
DWORD
WINAPI
Consumer(LPVOID
para)

//
i表示第i个消费者
int
i
=
*(int
*)para;
int
ptr;
//
待消费的内容的指针
printf("
猪头-%03d:
猪头我来啦!\n",
i);
Sleep(300);
while
(1)

printf("
猪头-%03d:
我要吃.........!\n",
i);
//
等待产品
P(g_semProduct);
//
有产品,先锁住缓冲区
g_buf
P(g_mutex);
//
记录消费的物品
ptr
=
g_buf.start;
//
再移动缓冲区指针
g_buf.start
=
(g_buf.start+1)%BUFFER_NUM;
//
让其他消费者或生产者使用
g_buf
V(g_mutex);
printf("
猪头-%03d:
我吃
buf[%d]
=
%s\n",
i,
ptr,
thing[g_buf.product[ptr]]);
Sleep(rate*rand()%10+110);
//
消费完毕,并释放一个缓冲
printf("
猪头-%03d:
我爽了!
buf[%d]
=
%s\n",
i,
ptr,
thing[g_buf.product[ptr]]);
V(g_semBuffer);

return
0;

//
生产者线程
DWORD
WINAPI
Producer(LPVOID
para)

int
i
=
*(int
*)para
-
CONSUMER_NUM;
int
ptr;
int
data;
//
产品
printf("工作狂-%03d:
我来啦!\n",
i);
Sleep(300);
while
(1)

printf("工作狂-%03d:
我干干干…………\n",
i);
Sleep(rate*rand()%10+110);
data
=
rand()%10;
printf("工作狂-%03d:
搞出一个东西
data
=
%s!\n",
i,
thing[data]);
//
等待存放空间
P(g_semBuffer);
//
有地方,先锁住缓冲区
g_buf
P(g_mutex);
//
记录消费的物品
ptr
=
g_buf.end;
//
再移动缓冲区指针
g_buf.end
=
(g_buf.end+1)%BUFFER_NUM;
//
让其他消费者或生产者使用
g_buf
V(g_mutex);
printf("工作狂-%03d:
搁到
buf[%d]
=
%s\n",
i,
ptr,
thing[data]);
g_buf.product[ptr]
=
data;
Sleep(rate/2*rand()%10+110);
//
放好了完毕,释放一个产品
printf("工作狂-%03d:
buf[%d]
=
%s
放好了,大家吃!\n",
i,
ptr,
thing[g_buf.product[ptr]]);
V(g_semProduct);

return
0;

int
main(int
argc,
char
*argv[])

//
线程技术,前面为消费者线程,后面为生产者线程
HANDLE
hThread[CONSUMER_NUM+PRODUCER_NUM];
//
线程计数
//srand(time());
DWORD
tid;
int
i=0;
//
初始化信号量
g_mutex
=
CreateSemaphore(NULL,
BUFFER_NUM,
BUFFER_NUM,
"mutexOfConsumerAndProducer");
g_semBuffer
=
CreateSemaphore(NULL,
BUFFER_NUM,
BUFFER_NUM,
"BufferSemaphone");
g_semProduct
=
CreateSemaphore(NULL,
0,
BUFFER_NUM,
"ProductSemaphone");
if
(
!g_semBuffer
||
!g_semProduct
||
!g_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;
参考技术A 这个问题蛮好的
我给你个程序
给我加分啊
#include <windows.h>
#include <stdio.h>
#include <stdlib.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 10 /* 消费者个数 */
#define PRODUCER_NUM 10 /* 生产者个数 */
#define BUFFER_NUM 4 /* 缓冲区个数 */

char *thing[10] = "猪脸", "牛鞭", "羊腰", "驴蹄", "狼心", "狗肺", "猴肝", "老虎屁股", "大象肚", "河马大肠";

struct Buffer

int product[BUFFER_NUM]; // 缓冲区
int start, end; // 两个指针
g_buf;

Semaphore g_semBuffer, g_semProduct, g_mutex;

// 消费者线程
DWORD WINAPI Consumer(LPVOID para)

// i表示第i个消费者
int i = *(int *)para;
int ptr; // 待消费的内容的指针

printf(" 猪头-%03d: 猪头我来啦!\n", i);

Sleep(300);
while (1)

printf(" 猪头-%03d: 我要吃.........!\n", i);
// 等待产品
P(g_semProduct);

// 有产品,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.start;

// 再移动缓冲区指针
g_buf.start = (g_buf.start+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf(" 猪头-%03d: 我吃 buf[%d] = %s\n", i, ptr, thing[g_buf.product[ptr]]);

Sleep(rate*rand()%10+110);

// 消费完毕,并释放一个缓冲
printf(" 猪头-%03d: 我爽了! buf[%d] = %s\n", i, ptr, thing[g_buf.product[ptr]]);
V(g_semBuffer);

return 0;


// 生产者线程
DWORD WINAPI Producer(LPVOID para)

int i = *(int *)para - CONSUMER_NUM;
int ptr;
int data; // 产品

printf("工作狂-%03d: 我来啦!\n", i);

Sleep(300);
while (1)

printf("工作狂-%03d: 我干干干…………\n", i);
Sleep(rate*rand()%10+110);

data = rand()%10;
printf("工作狂-%03d: 搞出一个东西 data = %s!\n", i, thing[data]);
// 等待存放空间
P(g_semBuffer);

// 有地方,先锁住缓冲区 g_buf
P(g_mutex);

// 记录消费的物品
ptr = g_buf.end;

// 再移动缓冲区指针
g_buf.end = (g_buf.end+1)%BUFFER_NUM;

// 让其他消费者或生产者使用 g_buf
V(g_mutex);

printf("工作狂-%03d: 搁到 buf[%d] = %s\n", i, ptr, thing[data]);
g_buf.product[ptr] = data;

Sleep(rate/2*rand()%10+110);

// 放好了完毕,释放一个产品
printf("工作狂-%03d: buf[%d] = %s 放好了,大家吃!\n", i, ptr, thing[g_buf.product[ptr]]);
V(g_semProduct);

return 0;


int main(int argc, char *argv[])

// 线程技术,前面为消费者线程,后面为生产者线程
HANDLE hThread[CONSUMER_NUM+PRODUCER_NUM]; // 线程计数

//srand(time());
DWORD tid;
int i=0;

// 初始化信号量
g_mutex = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "mutexOfConsumerAndProducer");
g_semBuffer = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone");
g_semProduct = CreateSemaphore(NULL, 0, BUFFER_NUM, "ProductSemaphone");

if ( !g_semBuffer || !g_semProduct || !g_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;
本回答被提问者采纳

以上是关于用C语言实现--生产者与消费者的问题(PV操作)的主要内容,如果未能解决你的问题,请参考以下文章

用C语言编写程序:生产者和消费者之间实现同步与互斥问题

请问如何用C语言实现“生产者与消费者问题”?(最好附上完整的C语言源代码)

生产者-消费者”问题 用C语言编写

用c语言或c++编写编程实现生产者消费者或读写者的同步问题

实验四

实验四生产者和消费者