生产者与消费者模式 适用场景
生产者和消费者模式适用于生产者和消费者之间存在数据交换的场景。在这种模式中,生产者负责生产数据并将其放入缓冲区,而消费者负责从缓冲区中取出数据并进行处理。这种模式的优点是可以实现生产者和消费者之间的解耦,使得它们可以独立地进行操作,从而提高了系统的并发性和可扩展性。
生产者和消费者模式适用于许多场景,例如:
- 操作系统中的进程和线程之间的通信;
- 数据库系统中的读写操作;
- 网络通信中的数据传输;
- 多线程编程中的任务队列等。
总之,只要存在生产者和消费者之间的数据交换,就可以考虑使用生产者和消费者模式来实现。文章来源:https://www.toymoban.com/news/detail-435618.html
代码实例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
#define SHM_KEY 1234
int main() {
int shmid;
int *shmaddr;
int in = 0, out = 0;
sem_t *empty, *full, *mutex;
// 创建共享内存
shmid = shmget(SHM_KEY, BUFFER_SIZE * sizeof(int), IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(1);
}
// 将共享内存附加到进程的地址空间
shmaddr = shmat(shmid, NULL, 0);
if (shmaddr == (int *) -1) {
perror("shmat");
exit(1);
}
// 初始化信号量
empty = sem_open("empty", O_CREAT, 0666, BUFFER_SIZE);
full = sem_open("full", O_CREAT, 0666, 0);
mutex = sem_open("mutex", O_CREAT, 0666, 1);
if (empty == SEM_FAILED || full == SEM_FAILED || mutex == SEM_FAILED) {
perror("sem_open");
exit(1);
}
// 生产者进程
if (fork() == 0) {
int item;
while (1) {
item = rand() % 100; // 生产一个随机数
sem_wait(empty); // 等待缓冲区非满
sem_wait(mutex); // 互斥访问缓冲区
shmaddr[in] = item; // 将 item 放入共享内存
in = (in + 1) % BUFFER_SIZE;
printf("Producer produced item %d\n", item);
sem_post(mutex); // 释放缓冲区
sem_post(full); // 增加缓冲区中的项目数
}
}
// 消费者进程
if (fork() == 0) {
int item;
while (1) {
sem_wait(full); // 等待缓冲区非空
sem_wait(mutex); // 互斥访问缓冲区
item = shmaddr[out]; // 从共享内存中取出一个项目
out = (out + 1) % BUFFER_SIZE;
printf("Consumer consumed item %d\n", item);
sem_post(mutex); // 释放缓冲区
sem_post(empty); // 增加缓冲区中的空闲位置数
}
}
// 等待子进程结束
wait(NULL);
wait(NULL);
// 删除共享内存和信号量
shmdt(shmaddr);
shmctl(shmid, IPC_RMID, NULL);
sem_unlink("empty");
sem_unlink("full");
sem_unlink("mutex");
return 0;
}
在该示例中,我们使用了共享内存和信号量来实现生产者和消费者模式。首先,我们使用 shmget()
函数创建共享内存,然后使用 shmat()
函数将共享内存附加到进程的地址空间中。接着,我们使用 sem_open()
函数初始化信号量。在生产者进程中,当共享内存非满时,生产者将 item 放入共享内存,并增加 full 信号量的值;在消费者进程中,当共享内存非空时,消费者从共享内存中取出一个项目,并增加 empty 信号量的值。由于信号量的特性,当信号量的值为 0 时,调用 sem_wait()
函数的进程将被阻塞,直到信号量的值大于 0。因此,我们不需要使用 while 循环来轮询共享内存的状态。最后,我们使用 shmdt()
函数将共享内存从进程的地址空间中分离,并使用 shmctl()
函数删除共享内存。同时,我们使用 sem_unlink()
函数删除信号量。文章来源地址https://www.toymoban.com/news/detail-435618.html
到了这里,关于【设计模式】C语言使用共享内存和信号量,完美实现生产者与消费者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!