实现进程间通信的几种方式

实现进程间通信的几种方式

一. 传统的进程间通信 - 管道文件

管道是 UNIX 系统中最古老的进程间通信技术。早期的管道是半双工通信,现有的系统管道是全双工通信。管道是一种特殊的文件,数据在文件中是流动的,读取之后自动消失,如果文件中没有数据则会阻塞。

1. 有名管道

有名管道基于有文件名的管道文件进行通信。

编程模型
  • 进程 A

    • 创建管道
    • 打开管道(写)
    • 写数据
    • 关闭管道
    • 删除管道
  • 进程 B

    • 打开管道(读)
    • 读数据
    • 关闭管道
创建有名管道文件
  1. 命令:mkfifo

  2. 函数:

    int mkfifo(const char *pathname, mode_t mode);
    
    • 功能:创建有名管道
    • pathname:管道文件路径
    • mode:管道文件权限(如 0664)

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ca7cc69bfb5942079df22f3c56310464.png

代码实现

进程 A

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, const char* argv[]) {if (mkfifo("fifo", 0644)) {perror("mkfifo");return -1;}int fd = open("fifo", O_WRONLY);if (fd < 0) {perror("open");unlink("fifo");return -1;}char buf[256] = {};for (;;) {printf(">>>>>>>>");fgets(buf, sizeof(buf), stdin);write(fd, buf, strlen(buf));if (0 == strncmp("quit", buf, 4)) {printf("quit\n");break;}}close(fd);usleep(1000);unlink("fifo");return 0;
}

进程 B

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, const char* argv[]) {int fd = open("fifo", O_RDONLY);if (fd < 0) {perror("open");return -1;}char buf[1024] = {};int n = read(fd, buf, sizeof(buf));while (n > 0) {write(1, buf, n);n = read(fd, buf, sizeof(buf));}close(fd);return 0;
}

2. 匿名管道

匿名管道只适合通过 fork 创建的父子进程之间通信。

函数
int pipe(int pipefd[2]);
  • pipefd[0] 用于读
  • pipefd[1] 用于写
编程模型
  • 父进程

    • 获取一对 fd
    • 创建子进程
    • 关闭读
    • 写数据
    • 关闭写
  • 子进程

    • 共享一对 fd
    • 关闭写
    • 读数据
    • 关闭读

在这里插入图片描述

代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>int main(int argc, char *argv[]) {int fd[2];if (pipe(fd) == -1) {perror("pipe");return 1;}pid_t pid = fork();if (pid == -1) {perror("fork");return 1;}if (pid > 0) {// 父进程close(fd[0]);for (;;) {char buf[256];printf("请输入要发送的消息:");fgets(buf, sizeof(buf), stdin);buf[strcspn(buf, "\n")] = 0;write(fd[1], buf, strlen(buf) + 1);if (strcmp(buf, "quit") == 0) break;}close(fd[1]);} else {// 子进程close(fd[1]);for (;;) {char buf[256];ssize_t bytesRead = read(fd[0], buf, sizeof(buf));if (bytesRead > 0) {printf("收到消息:%s\n", buf);if (strcmp(buf, "quit") == 0) break;} else {break;}}close(fd[0]);}return 0;
}

二. XSI 进程间通信

XSI 是 X/Open 公司制定的用于进程间通信的系统接口。

共享内存

共享内存允许多个进程共享一块内存,由内核负责协调管理。

函数
  • 创建/获取共享内存:

    int shmget(key_t key, size_t size, int shmflg);
    
  • 映射共享内存:

    void *shmat(int shmid, const void *shmaddr, int shmflg);
    
  • 取消映射:

    int shmdt(const void *shmaddr);
    
  • 控制共享内存:

    int shmctl(int shmid, int cmd, struct shmid_ds *buf);
    
编程模型
  • 进程 A

    • 创建共享内存
    • 映射共享内存
    • 写数据并通知其他进程
    • 收到通知并读数据
    • 取消映射
    • 删除共享内存
  • 进程 B

    • 获取共享内存
    • 映射共享内存
    • 收到通知并读数据
    • 写数据并通知其他进程
    • 取消映射

在这里插入图片描述

代码实现

进程 A

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>char* shm;void sigint(int num) {printf("已收到信号\n");printf("%s\n", shm);
}int main(int argc, const char* argv[]) {printf("进程ID为:%u\n", getpid());// 创建共享内存int shmid = shmget(ftok(".", 110), 4096, IPC_CREAT | 0666);if (shmid == -1) {perror("shmget");return 1;}// 映射共享内存shm = (char*)shmat(shmid, NULL, 0);if (shm == (void*)-1) {perror("shmat");shmctl(shmid, IPC_RMID, NULL);return 1;}signal(SIGRTMIN, sigint);// 写入数据并通知其他进程pid_t pid = 0;printf("请输入与我通信的进程号:");scanf("%d", &pid);for (;;) {printf(">>>>>>");scanf("%s", shm);kill(pid, SIGRTMIN);if (0 == strcmp(shm, "quit")) {printf("通信结束\n");break;}}// 取消映射shmdt(shm);// 删除共享内存shmctl(shmid, IPC_RMID, NULL);return 0;
}

进程 B

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <string.h>char *shm;void sigint(int num) {printf("已收到信号\n");printf("%s\n", shm);
}int main(int argc, const char* argv[]) {// 打印出进程号pid_t pid = getpid();printf("进程ID为:%u\n", pid);// 获取共享内存int shmid = shmget(ftok(".", 110), 4096, IPC_CREAT | 0666);if (shmid == -1) {perror("shmget");return 1;}// 映射共享内存shm = (char*)shmat(shmid, NULL, 0);if (shm == (void*)-1) {perror("shmat");shmctl(shmid, IPC_RMID, NULL);return 1;}// 收到通知并读取数据signal(SIGRTMIN, sigint);// 写入数据并通知其他进程pid_t pids = 0;printf("请输入与我通信的进程号:");scanf("%u", &pids);for (;;) {printf(">>>>>>");scanf("%s", shm);kill(pids, SIGRTMIN);if (0 == strcmp(shm, "quit")) {printf("通信结束\n");break;}}// 取消映射shmdt(shm);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1522675.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【重学 MySQL】二、MySQL 介绍

【重学 MySQL】二、MySQL 介绍 MySQL 概述MySQL 的主要特点MySQL 的应用场景结论 MySQL 发展史初始创建与发布开源与快速成长重要版本发布收购与变革分支与竞争持续发展与现代应用 关于 MySQL8.0主要新特性和改进兼容性和迁移应用场景总结 为什么选择 MySQLOracle VS MySQL基本…

Java-线程的生命周期7大状态

在 Java 中&#xff0c;线程的生命周期可以分为多个状态&#xff0c;这些状态描述了线程从创建到终止的整个过程。Java 线程的生命周期主要包括以下七大状态&#xff1a; 1.新建状态&#xff08;New&#xff09; 当一个线程对象被创建但尚未调用 start() 方法时&#xff0c;线…

mysql高级sql

一&#xff0c;查询 1.按关键字排序 1.1用 **ORDER BY** 语句来实现排序&#xff1a; - ORDER BY 语句用于对查询结果进行排序。可以根据一个或多个字段的值进行升序&#xff08;ASC&#xff09;或降序&#xff08;DESC&#xff09;排序。1.2排序可针对一个或多个字段&#…

终于有人把数据中台讲明白了

在大数据发展的黄金期&#xff0c;几乎所有的高科技企业都在思考一个问题&#xff1a;海量数据作为大多数企业发展不可避免的一个趋势之后&#xff0c;企业该怎么去应用这部分数据资产&#xff0c;会对其商业产生什么影响&#xff0c;如何使数据对企业产生正面的推动而不是成为…

mysql高级知识之集群

一、安装 源码编译MySQL,若需要MySQLtar包可私信我 #创建数据目录 mkdir /data/mysql -p#安装相关依赖 yum install libtirpc-devel-0.2.4-0.16.el7.x86_64.rpm yum install cmake gcc-c++ openssl-devel ncurses-devel.x86_64 libtirpc-devel-1.3.3-8.el9_4.x86_64.rpm rpcgen…

安防视频综合管理系统EasyCVR视频汇聚平台集群部署出现状态不同步的情况是什么原因?

随着视频监控技术的快速发展&#xff0c;各类视频资源的整合、管理与分发成为了安防行业的重要挑战。视频综合管理系统EasyCVR视频汇聚平台通过集群部署&#xff0c;实现了视频资源的高效整合与管理。集群部署不仅能够提升系统的处理能力和稳定性&#xff0c;还能有效避免单点故…

JVM面试(四)类加载器和双亲委派机制

什么是类加载器&#xff1f; 简单来说的话&#xff0c;是用于实现“类加载动作”的加载器 “通过一个类的全限定名来获取描述该类的二进制字节流”这个动作放到Java虚拟机外部去实现&#xff0c;以便让应用程序自己决定如何去获取所需的类。实现这个动作的代码被称为“类加载器…

Ollama拉起本地模型以及rag系统部署。

什么是 Ollama &#xff1f; Ollama 是一个简明易用的本地大模型运行框架。能在本地启动并运行 Llama、qwen、Gemma 及其他大语言模型&#xff0c;没有GPU资源照样可以拉起模型&#xff0c;和LocalAI 比较类似&#xff0c;但是加载模型更容易。 1.安装 安装后运行&#xff0c…

解剖学上合理的分割:通过先验变形显式保持拓扑结构|文献速递--基于深度学习的医学影像病灶分割

Title 题目 Anatomically plausible segmentations: Explicitly preserving topology through prior deformations 解剖学上合理的分割&#xff1a;通过先验变形显式保持拓扑结构 01 文献速递介绍 进行环向应变或壁厚度的计算&#xff0c;这些测量通常用于诊断肥厚性心肌病…

Vue前端路由详解——以Ruoyi框架为案例学习

Vue路由 Vue路由详解_vue 页面路由-CSDN博客 路由模式 Vue 的路由模式&#xff1a;hash 模式和 history 模式的区别_vue路由history和hash的区别-CSDN博客 URL格式&#xff1a; Hash模式&#xff1a;URL中包含#号&#xff0c;用于区分页面部分&#xff0c;实际请求的页面地址…

【深度学习与NLP】——词嵌入Embedding技术

目录 1.词嵌入的作用 2.嵌入矩阵的计算 3.Embedding层的代码实验 词嵌入&#xff08;Embedding&#xff09;技术是一种将词汇映射到低维连续向量空间的方法。将离散的单词数据处理成连续且固定长度的向量&#xff0c;使模型可以学习和处理语义信息。 假设需要将["Are&…

【MySQL00】【 杂七杂八】

文章目录 一、前言二、MySQL 文件1. 参数文件2. 日志文件3. 套接字文件4. pid 文件5. 表结构定义文件6. InnoDB 存储引擎文件 二、BTree 索引排序三、InnoDB 关键特性1. 插入缓冲1.1 Insert Buffer 和 Change Buffer1.1 缓冲合并 2. 两次写2. 自适应哈希索引3. 异步IO4. 刷新邻…

关于武汉芯景科技有限公司的A/D转换芯片XJ3021开发指南(兼容MCP3021)

一、芯片引脚介绍 1.芯片引脚 2.引脚描述 二、系统结构图 三、时序&#xff08;IIC通信&#xff09; 四、程序代码 XJ3021.C /** XJ3021.c** Created on: 2024年8月23日* Author: Administrator*/ #include "softiic.h" #include "XJ3021.h" #inc…

《Cloud Native Data Center Networking》(云原生数据中心网络设计)读书笔记 -- 09部署OSPF

本章的目的是帮助网络工程师确定网络的理想 OSPF 配置。本章将回答以下问题 应何时在数据中使用OSPF ?配置 OSPF 的关键设计原则是什么?OSPFv2 和 OSPFv3 之间有什么区别&#xff0c;应如何使用?如何在路由协议栈中配置 OSPF ?如何在服务器上配置 OSPF&#xff0c;例如为容…

【MySQL08】【死锁】

文章目录 一、前言二、查看事务加锁情况1. 使用 information_schema 数据库中表获取锁信息1.1 INNODB_TRX1.2 INNODB_LOCKS1.3 INNODB_LOCK_WAITS 2. 使用 SHOW ENGIN INNODB STATUS 获取锁信息 三、死锁四、参考内容 一、前言 最近在读《MySQL 是怎样运行的》、《MySQL技术内…

Android之Handler的post方法和sendMessage的区别

目录 post 方法方法特点 sendMessage 方法方法特点 使用场景区别总结 Handler 类在 Android 中用于在不同线程之间传递消息和执行代码。它提供了两种主要的方式来执行任务&#xff1a;通过 post 方法和通过 sendMessage 方法。这两种方法有不同的使用场景和特点。 post 方法 方…

浅谈架构实战

目录 背景 1 架构演变 2 如何实现高层的复用 2 中台产生案例 3 技术架构的核心要点 4 技术架构的高可用案例 背景 业务架构、数据架构、应用架构和技术架构它们是相互关联和相互支持的&#xff0c;共同构成了企业的总体架构&#xff0c;业务架构是源头&#xff0c;然后才…

自动生成对话视频!如何使用Captions的AI视频生成与编辑API工具?

Captions公司最近发布了一套AI驱动的视频生成和编辑API工具&#xff0c;为创作者和开发者提供了一个强大的视频创作生态系统。这个系统包含AI Creator、AI Twin、AI Edit、和AI Translate四大核心功能&#xff0c;每个工具都针对不同的创作需求进行优化。下面我们就一起来详细测…

第九周:机器学习

目录 摘要 Abstract 一、RNN 1、引入 2、RNN的分类 二、LSTM 1、基本结构 2、具体步骤 3、举例说明 4、原理理解 总结 摘要 本周主要围绕RNN进行探讨&#xff0c;从为什么需要这类”循环网络“入手&#xff0c;提到了”slot filling“技术&#xff0c;接着又对R…