【设计模式】C语言使用共享内存和信号量,完美实现生产者与消费者模式

这篇具有很好参考价值的文章主要介绍了【设计模式】C语言使用共享内存和信号量,完美实现生产者与消费者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

生产者与消费者模式 适用场景

生产者和消费者模式适用于生产者和消费者之间存在数据交换的场景。在这种模式中,生产者负责生产数据并将其放入缓冲区,而消费者负责从缓冲区中取出数据并进行处理。这种模式的优点是可以实现生产者和消费者之间的解耦,使得它们可以独立地进行操作,从而提高了系统的并发性和可扩展性。

生产者和消费者模式适用于许多场景,例如:

  1. 操作系统中的进程和线程之间的通信;
  2. 数据库系统中的读写操作;
  3. 网络通信中的数据传输;
  4. 多线程编程中的任务队列等。

总之,只要存在生产者和消费者之间的数据交换,就可以考虑使用生产者和消费者模式来实现。

代码实例

#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模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【设计模式】使用 go 语言实现简单工厂模式

    最近在看《大话设计模式》,这本书通过对话形式讲解设计模式的使用场景,有兴趣的可以去看一下。 第一篇讲的是 简单工厂模式 ,要求输入两个数和运算符号,得到运行结果。 这个需求不难,难就难在类要怎么设计,才能达到可复用、维护性强、可拓展和灵活性高。 运

    2024年02月05日
    浏览(44)
  • 【C++】Windows下共享内存加信号量实现进程间同步通信

    目录 一,函数清单 1.CreateFileMapping 方法 2.OpenFileMapping 方法 3.MapViewOfFile 方法 4.UnmapViewOfFile 方法 5.CreateSemaphore 方法 6. OpenSemaphore 方法 7.WaitForSingleObject 方法 8.ReleaseSemaphore 方法 9.CloseHandle 方法 10.GetLastError 方法 二,单共享内存单信号量-进程间单向通信 共享内存管理文

    2024年02月08日
    浏览(40)
  • 【Linux】进程间通信——system V共享内存 | 消息队列 | 信号量

    共享内存是一种在多个进程之间进行进程间通信的机制。它允许多个进程访问相同的物理内存区域,从而实现高效的数据交换和通信。 因为 进程具有独立性(隔离性) ,内核数据结构包括对应的代码、数据与页表都是独立的。OS系统为了让进程间进行通信,必须让不同的进

    2024年02月15日
    浏览(50)
  • 设计模式之避免共享的设计模式Copy-on-Write模式

    设计模式之避免共享的设计模式Immutability(不变性)模式 设计模式之并发特定场景下的设计模式 Two-phase Termination(两阶段终止)模式 Java 里 String 在实现 replace() 方法的时候,并没有更改原字符串里面 value[] 数组的内容,而是创建了一个新字符串,这种方法在解决不可变对象

    2024年01月21日
    浏览(36)
  • 设计模式之避免共享的设计模式 Thread-Specific Storage 模式

    设计模式之避免共享的设计模式Immutability(不变性)模式 设计模式之并发特定场景下的设计模式 Two-phase Termination(两阶段终止)模式 设计模式之避免共享的设计模式Copy-on-Write模式 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 Thread-Specific Storage(

    2024年01月21日
    浏览(33)
  • Linux之进程间通信——system V(共享内存、消息队列、信号量等)

    本文介绍了另一种进程间通信——system V,主要介绍了共享内存,消息队列、信号量,当然消息队列了信号量并非重点,简单了解即可。 共享内存 :不同的进程为了进行通信看到的同一个内存块,该内存块被称为共享内存。 进程具有独立性,它的内核数据结构包括对应的代

    2024年02月08日
    浏览(57)
  • 设计模式之【享元模式】,共享单车火起来并不是没有原因的

    全网最全最细的【设计模式】总目录,收藏起来慢慢啃,看完不懂砍我 享元模式(Flyweight Pattern)也叫蝇量模式,又称为轻量级模式,是 对象池 的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。提供了减少对象数量从而改善应用所需的对

    2024年02月05日
    浏览(35)
  • C++11并发与多线程笔记(7) 单例设计模式共享数据分析、解决,call_once

    程序灵活,维护起来可能方便,用设计模式理念写出来的代码很晦涩,但是别人接管、阅读代码都会很痛苦 老外应付特别大的项目时,把项目的开发经验、模块划分经验,总结整理成设计模式 中国零几年设计模式刚开始火时,总喜欢拿一个设计模式往上套,导致一个小小的

    2024年02月12日
    浏览(40)
  • 【转存】Go语言设计模式

    导语| 设计模式是针对软件设计中常见问题的工具箱,其中的工具就是各种经过实践验证的解决方案。即使你从未遇到过这些问题,了解模式仍然非常有用,因为它能指导你如何使用面向对象的设计原则来解决各种问题,提高开发效率,降低开发成本;本文囊括了GO语言实现的

    2024年02月03日
    浏览(35)
  • 基于C语言的面向对象设计模式(持续更新)

    首先这篇文章只是初步的尝试,不涉及过于高深的编程技巧;同时需要表明的是, 面向对象只是一种思想 ,不局限于什么样的编程语言,不可否认的是基于面向对象特性而设计的语言确实要比面向过程式的语言更加容易进行抽象和统筹,可以说面向对象的设计模式可以很大

    2024年04月10日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包