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

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

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

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 = 0i <REPEATSi++)

{

/* 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 = 0i <REPEATSi++)

{

/* 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

}

虽然是2014年的问题,但是我现在也遇到了这个麻烦,回答留在这帮助一下以后遇到这个问题的人。同时显示不同的数我能想到一种方法,但是需要的是fpga的支持,这种方法需要在每个数码管前面放一个锁存器,用这个锁存器向这个数码管提供显示数据,当需要修改数码管显示的时候,更新锁存器内容就行了,这种方式也称为直流法(直接驱动);还有一种不同时显示但是可以给人一种同时显示的感觉,那就是先显示第一个,再显示第二个,再显示第三个,再显示第四个,只要时间间隔够短,在人们看来就是同时显示,这种方法不需要锁存器的支持,因为我们本来就是一次显示一个,这种方式称为动态扫描


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存