当前位置: 首页 > java >正文

IPC 进程间通信 interprocess communicate

三大类:


1、古老的通信方式

无名管道      有名管道      信号

2、IPC对象通信 systemvBSD suse fedora kernel.org

消息队列(用的相对少,这里不讨论)

共享内存

信号量集

3、socket通信

网络通信

线程信号,posix sem_init

特列:古老的通信方式中信号是唯一的异步通信
所有的通信方式中共享内存是唯一的最高效

管道==》无名管道、有名管道

无名管道 ===》pipe ==》只能给有亲缘关系进程通信
有名管道===》fifo==》可以给任意单机进程通信

无名管道

1、管道是半双工的工作模式
2、所有的管道都是特殊的文件不支持定位操作。Iseek->>fd fseek->>FILE*
3、管道是特殊文件,读写使用文件IO。fgets,fread,fgetc,(这个有缓冲区)

open,read,write,close(首选)

1,读端存在,一直向管道中去写,超过64k,写会阻塞。

2.写端是存在的,读管道,如果管道为空的话,读会阻塞。

3.管道破裂,,读端关闭,写管道。

4.read0,写端关闭,如果管道没有内容,read;

使用框架:
创建管道==》读写管道==》关闭管道

1、无名管道===》管道的特例===>pipe函数

特性:
1.1亲缘关系进程使用
1.2 有固定的读写端

流程:
创建并打开管道:pipe函数
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建并打开一个无名管道
参数:pipefd[0]==>无名管道的固定读端

读堵塞

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc,char *argv[])
{int fd[2]={0};int ret = pipe(fd);if(-1==ret){perror("pipe");return 1;}pid_t pid =fork();if(pid>0){close(fd[0]);char buf[]="hello,child";sleep(3);write(fd[1], buf,sizeof(buf)+1);}else if(pid==0){close(fd[1]);char buf[50]={0};read(fd[0], buf, sizeof(buf));printf("child,buf :%s\n",buf);}else{perror("fork");return 1;}return 0;
}

写堵塞:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main(int argc, char *argv[])
{int fd[2]={0};// create pipe + open pipe int ret = pipe(fd);if(-1 == ret){perror("pipe");return 1;}pid_t pid = fork();if(pid>0){//write fd close(fd[0]);char buf[1024]={0};memset(buf,'a',sizeof(buf));int i = 0 ;for(i=0;i<65;i++){write(fd[1],buf,sizeof(buf));printf("i is %d\n",i);}}else if(0==pid){// read onlyclose(fd[1]);sleep(5);char buf[50]={0};read(fd[0],buf,sizeof(buf));printf("child ,buf:%s\n",buf);}else {perror("fork");return 1;}return 0;
}

注意:管道的创建必须在fork之前

有名管道

有名管道===》fifo==》有文件名称的管道。   文件系统中可见

框架:
创建有名管道==》打开有名管道==》读写管道==》关闭管道==》卸载有名管道

有名管道的打开,会堵塞。

1.创建:mkfifo

#include <sys/types.h>
#include <sys/stat.h>
remove0;int mkfifo(const char *pathname, mode_t mode);
功能:在指定的pathname路径+名称下创建一个权限为mode的有名管道文件。
参数:pathname要创建的有名管道路径+名称mode 8进制文件权限。
返回值:成功0失败-1;

2.打开有名管道 open

注意:该函数使用的时候要注意打开方式,
因为管道是半双工模式,所有打开方式直接决定
当前进程的读写方式。
一般只有如下方式:
int fd-read = open("./fifo",O_RDONLY); ==>fd 是固定读端
int fd-write = open("./fifo",O_WRONLY); ==>fd 是固定写端
不能是O_RDWR方式打开文件。
不能有O_CREAT选项,因为创建管道有指定的mkfifo函数

3、管道的读写:文件IO

读: read(fd-read,buff,sizeof(buff);
写 : write(fd-write,buff,sizeof(buff);

4、关闭管道:
close(fd)

5、卸载管道:remove()

int unlink(const char *pathname);
功能:将指定的pathname管道文件卸载,同时
从文件系统中删除。
参数:ptahtname 要卸载的有名管道
返回值:成功0
失败-1;

进程间通信===》信号通信

应用:异步通信(时间随机)。中断(被更高优先级的进程打断,等其工作完之后再回到本程序)。
1~64;32应用编程。

信号处理,忽略9和19.

共享内存

IPC对象操作通用框架:
Ox ftok
key值 ==>申请 ==》读写 ==》关闭 ==》卸载

key值:===》唯一键值
创建方式有三种:

1、IPC_PRIVATE固定的私有键值,其值等于 OxO,一般用于有亲缘关系的进程间使用。

2、ftok(创建临时键值。

#include <sys/types.h>
#include <sys/ipc.h>
"/etc"!
key_t ftok(const char *pathname, int proj_id);
功能:通过该函数可以将pathname指定的路径用来以
proj_id生成唯一的临时键值。
参数:pathname 路径+名称===》任意文件,只要不会
被删除重建即可。
proj_id 整形的数字,一般用ASCll码的单字符
表示与参数1的运算。
返回值:成功返回唯一键值
失败-1;

ipcs :进程间通信命令显示

ipcrm:进程间通信的删除

eg:

写:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{key_t key = ftok("./", '!');if (-1 == key){perror("ftok");return 1;}printf("key is 0x%x\n", key);int shmid = shmget(key, 4096, IPC_CREAT | 0666);if (-1 == shmid){perror("shmid");return 1;}void *p = shmat(shmid, NULL, !SHM_RDONLY);if ((void *)-1 == p){perror("shmat");return 1;}char buf[] = "hello,this is shm test";// strcpy(p,buf);memcpy(p, buf, strlen(buf));shmdt(p);return 0;
}

读:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv)
{key_t key = ftok("./", '!');if (-1 == key){perror("ftok");return 1;}printf("key is 0x%x\n", key);int shmid = shmget(key, 4096, IPC_CREAT | 0666);if (-1 == shmid){perror("shmid");return 1;}void *p = shmat(shmid, NULL, !SHM_RDONLY);if ((void *)-1 == p){perror("shmat");return 1;}char buf[4096] = {0};// strcpy(p,buf);memcpy(buf, p, sizeof(buf));printf("buf %s\n", buf);shmdt(p);// shmctl(shmid, IPC_RMID, NULL);return 0;
}

http://www.xdnf.cn/news/19597.html

相关文章:

  • 企业微信AI落地:如何选择企业微信服务商?
  • Axios拦截器:前端通信的交通警察[特殊字符]
  • 搭载AX650N高能效比智能视觉芯片——AX2050系列边缘计算盒,可应用在智慧安防交通仓储教育,人脸识别,明厨亮灶,安全生产,智能机器人等
  • table表格字段明细展示
  • 不透明指针
  • 【iOS】折叠cell
  • 《青衣剑客 · Claude》连载
  • 总线矩阵的原理
  • 如何将多个Excel报表合并为一个汇总文件?
  • N32G43x Bootloader 中 ENV 区的管理与实现
  • 前缀和(优化算法)
  • ClickHouse常见问题——ClickHouseKeeper配置listen_host后不生效
  • 面试 TOP101 动态规划专题题解汇总Java版(BM62 —— BM82)
  • 二、SVN基础命令速查表
  • leetcode 1792. 最大平均通过率 中等
  • 通过 select into outfile / load data infile 进行数据导入导出学习笔记
  • 开源项目_金融分析工具TradingAgents
  • 01数据结构-红黑树
  • python 数据类型【python进阶一】
  • java设计模式一、单例模式
  • 【K8s】整体认识K8s之Configmap、Secret/ResourceQuota资源配额/访问控制
  • Linux应用开发-windows,linux环境下相关工具
  • Adobe Illustrator 2025最新破解教程下载安装教程,Illustrator2025最新版下载
  • AI 安全与伦理:当大模型拥有 “决策能力”,我们该如何建立技术边界与监管框架?
  • 新手向:前端开发中的常见问题
  • NLP大语言模型数据准备
  • 基于 DNA 的原核生物与微小真核生物分类学:分子革命下的范式重构​
  • Shell编程(二):正则表达式
  • FastK v1.1 安装与使用-生信工具59
  • Gradle vs. Maven,Java 构建工具该用哪个?