使用信号量实现有限缓冲区的生产者和消费者问题(使用fork(),semget()等函数,能在GCC下运行)

如题所述

看我下面的代码, 父进程是消费者,子进程是生产者。

REPEATS 决定总共生产的次数 (可以自己修改)
CONSUMER_SPEED 决定消费的速度 (越大越慢,可以自己修改)
PRODUCER_SPEED 决定生产的速度 (越大越慢,可以自己修改)

我的例子里,生产者生产一个随机数。另外消费速度比生产速度慢,所以可以看到输出中,+++ (生产者) 开头的出现的比--- (消费者)多,当生产者结束后,就只有 --- 打印了。

对这个程序由什么问题,可以baidu hi我。在linux/unix下用 gcc 编译。

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/stat.h>

#define REPEATS (10) /* count of production/consumption */

#define MAX_BUFFER_SIZE (8)

typedef struct
{
int bottom;
int top;

int data[MAX_BUFFER_SIZE];
} STRUCT_BUFFER;

STRUCT_BUFFER * pBuffer = NULL;

/* Define speed of consumer/producer, change them as u like */
#define PRODUCER_SPEED (1) /* 1/sec */
#define CONSUMER_SPEED (2) /* 1/2sec */

int sem_consume; /* consumer sem */
int sem_produce; /* producer sem */
int shm_buffer; /* shared buffer */

#define FLAG (IPC_CREAT | S_IRWXU)

/* Init semphores & shared buffer */
void init()
{
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
} arg;

shm_buffer = shmget(0x1111, sizeof(STRUCT_BUFFER), FLAG);
pBuffer = shmat(shm_buffer, 0, 0);
memset(pBuffer, 0, sizeof(STRUCT_BUFFER));

sem_consume = semget(0x2222, 1, FLAG);
arg.val = 0;
if (semctl(sem_consume, 0, SETVAL, arg) < 0)
{
perror("Consumer");
exit(1);
}

sem_produce = semget(0x3333, 1, FLAG);
arg.val = MAX_BUFFER_SIZE;
if (semctl(sem_produce, 0, SETVAL, arg) < 0)
{
perror("Producer");
exit(1);
}
}

/* destroy semphores & shared buffer */
void deinit()
{
shmctl(shm_buffer, IPC_RMID, NULL);
semctl(sem_consume, 0, IPC_RMID);
semctl(sem_produce, 0, IPC_RMID);
}

int main()
{
int pid, i;
struct sembuf sbuf;

init();

printf("Start fork...\n");
pid = fork();

if (pid > 0)
{
/* parent process, consumer */
for (i = 0; i < REPEATS; i++)
{
/* Try decrementing 1 from consumer */
sbuf.sem_num=0;
sbuf.sem_op=-1;
sbuf.sem_flg=0;
semop(sem_consume, &sbuf, 1);

/* OK */
printf("Consumer get %6d\n", pBuffer->data[pBuffer->bottom]);
pBuffer->bottom = (pBuffer->bottom+1)%MAX_BUFFER_SIZE;

/* Try incrementing 1 to producer */
sbuf.sem_op = 1;
semop(sem_produce, &sbuf, 1);

sleep(CONSUMER_SPEED);
}
wait(0);
shmdt(pBuffer);
}
else if (pid == 0)
{
srand(time(NULL));
/* child process, producer */
for (i = 0; i < REPEATS; i++)
{
/* Try decrementing 1 from producer */
sbuf.sem_num=0;
sbuf.sem_op=-1;
sbuf.sem_flg=0;
semop(sem_produce, &sbuf, 1);

/* OK */
pBuffer->data[pBuffer->top] = (rand()%1000)*1000 + i + 1;
printf("Producer put %6d\n", pBuffer->data[pBuffer->top]);
pBuffer->top = (pBuffer->top+1)%MAX_BUFFER_SIZE;

/* Try incrementing 1 to consumer */
sbuf.sem_op = 1;
semop(sem_consume, &sbuf, 1);

sleep(PRODUCER_SPEED);
}
shmdt(pBuffer);
exit(0);
}

deinit();
return 0;
}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2010-11-07
写这个不是很难的。

有什么不懂得可以问我,我尽我所能帮你,账号就是QQ,我是计算机专业的。
相似回答