生产者消费者c语言代码_生产者消费者问题、父子进程、信号量(IPC机制):代码分享...
时间: 2023-06-26 09:06:01 浏览: 107
信号量来解决操作系统的消费者与生产者问题.rar_信号量_生产者 消费者_进程
以下是一个简单的生产者消费者问题的C语言代码,使用父子进程和信号量(IPC机制)实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define BUFFER_SIZE 5
#define MAX_ITEMS 50
int buffer[BUFFER_SIZE];
int in = 0, out = 0, count = 0;
int sem_id;
void producer(void);
void consumer(void);
void wait_and_lock(int sem_id);
void release_lock(int sem_id);
int main()
{
int pid;
// 创建信号量
sem_id = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT);
if (sem_id == -1)
{
perror("Error creating semaphore");
exit(EXIT_FAILURE);
}
// 初始化信号量
if (semctl(sem_id, 0, SETVAL, 1) == -1)
{
perror("Error initializing semaphore");
exit(EXIT_FAILURE);
}
// 创建生产者进程
pid = fork();
if (pid == 0)
{
// 子进程为生产者
producer();
exit(EXIT_SUCCESS);
}
else if (pid == -1)
{
perror("Error creating producer process");
exit(EXIT_FAILURE);
}
// 创建消费者进程
pid = fork();
if (pid == 0)
{
// 子进程为消费者
consumer();
exit(EXIT_SUCCESS);
}
else if (pid == -1)
{
perror("Error creating consumer process");
exit(EXIT_FAILURE);
}
// 等待子进程结束
wait(NULL);
wait(NULL);
// 删除信号量
if (semctl(sem_id, 0, IPC_RMID) == -1)
{
perror("Error deleting semaphore");
exit(EXIT_FAILURE);
}
return 0;
}
void producer(void)
{
int item;
for (int i = 0; i < MAX_ITEMS; i++)
{
// 生产一个物品
item = rand() % 100;
// 获取锁并添加物品到缓冲区
wait_and_lock(sem_id);
if (count < BUFFER_SIZE)
{
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
count++;
printf("Producer produced item %d\n", item);
}
release_lock(sem_id);
// 等待一段时间
sleep(rand() % 3);
}
}
void consumer(void)
{
int item;
for (int i = 0; i < MAX_ITEMS; i++)
{
// 获取锁并从缓冲区中取出物品
wait_and_lock(sem_id);
if (count > 0)
{
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
printf("Consumer consumed item %d\n", item);
}
release_lock(sem_id);
// 等待一段时间
sleep(rand() % 3);
}
}
void wait_and_lock(int sem_id)
{
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = SEM_UNDO;
if (semop(sem_id, operations, 1) == -1)
{
perror("Error locking semaphore");
exit(EXIT_FAILURE);
}
}
void release_lock(int sem_id)
{
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = 1;
operations[0].sem_flg = SEM_UNDO;
if (semop(sem_id, operations, 1) == -1)
{
perror("Error unlocking semaphore");
exit(EXIT_FAILURE);
}
}
```
在该代码中,我们创建了一个缓冲区(使用一个数组实现),一个生产者进程和一个消费者进程。两个进程通过信号量实现对缓冲区的访问同步。生产者进程随机生成一个物品并将其添加到缓冲区中,消费者进程从缓冲区中取出一个物品并将其消耗掉。当缓冲区满时,生产者进程等待直到缓冲区中有可用空间。当缓冲区为空时,消费者进程等待直到缓冲区有可用物品。
在该代码中,我们使用了Unix系统调用中的一些函数,包括fork()来创建进程,wait()来等待子进程退出,semget()来创建信号量,semctl()来初始化和删除信号量,semop()来操作信号量。这些函数可以通过man命令来查看其详细用法和参数。
阅读全文