unix 环境高级编程 c语言 --- 进程间通信5种方式汇总

本文详细介绍了Unix环境中进程间通信的五种方式:管道(包括有名和无名管道)、XSI进程间通信(如共享内存、消息队列)、以及信号量。讨论了各种通信方式的概念、特点及应用实例,帮助理解不同进程如何交换信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

何为进程间通信

进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。另外,系统空间是"公共场所",各进程均可以访问,所以内核也可以提供这样的条件。此外,还有双方都可以访问的外设。在这个意义上,两个进程当然也可以通过磁盘上的普通文件交换信息,或者通过"注册表"或其它数据库中的某些表项和记录交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作"进程间通信"。

分类

1 简单进程间通信: 
命令行参数、环境变量、信号、文件。
2 传统进程间通信: 
 管道(fifo/pipe)。
3 XSI进程间通信: 
 共享内存、消息队列、信号量。
4 网络进程间通信: 
 套接字socket。

关于简单进程间通信的方式前面已经讲过
接下来看看其他的5种

管道

概念:

管道是Linux支持的最初UnixIPC形式之一,具有以下特点:

管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);

单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

有名管道

在这里插入图片描述
我们通过创建客户端和服务端来读写

服务器

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int running = 1;

#define FIFO1 "/tmp/wfifo" 
#define FIFO2 "/tmp/rfifo"

void sigint_proc(int sig){
   
	running = 0;
}

int main(){
   
	signal(SIGINT,sigint_proc);
	int ret = mkfifo(FIFO1,0664);
	if(ret == -1){
   
		perror("mkfifo");
		return -1;
	}
	ret = mkfifo(FIFO2,0664);
	if(ret == -1){
   
		perror("mkfifo");
		return -1;
	}
	int wfd = open(FIFO1,O_RDWR|O_NONBLOCK);//打开管道用于写
	int rfd = open(FIFO2,O_RDWR|O_NONBLOCK);//打开管道用于读
	if(wfd == -1||rfd == -1){
   
		perror("open");
		return -1;
	}
	pid_t id;
	id = fork();
	if(id == -1){
   
		perror("fork");
		close(wfd);
		close(rfd);	
	}
	if(id == 0){
   
		for(;running;){
   
			char str[128] = {
   };
			fgets(str,128,stdin);
			if(write(wfd,str,strlen(str))<0){
   //在这个函数中阻塞
				break;
			}
		}
	}else{
   
		for(;running;){
   
			char str[128] = {
   };
			if(read(rfd,str,128)<0){
   
				if(errno == EAGAIN){
   
					continue;	
				}	
				break;
			}else
				printf("recv: %s",str);
		}
	}
	close(rfd);
	close(wfd);
	unlink(FIFO1);
	unlink(FIFO2);
	return 0;	
}

客户端

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>

#define FIFO1 "/tmp/wfifo" 
#define FIFO2 "/tmp/rfifo"


int main(){
   
	int wfd = open(FIFO2,O_RDWR);//打开管道用于写
	int rfd = open(FIFO1,O_RDWR);//打开管道用于读
	if(wfd == -1||rfd == -1){
   
		perror("open");
		return -1;
	}
	pid_t id;
	id = fork();
	if(id == -1){
   
		perror("fork");
		close(wfd);
		close(rfd);	
	}
	if(id == 0){
   
		for(;;){
   
			char str[128] = {
   };
			fgets(str,128,stdin);
			if(write(wfd,str,strlen(str))<=0)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HOVL_C++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值