Linux进程间通信学习笔记

本文详细介绍了Linux进程间通信(IPC)的各种方式,包括无名管道和命名管道(FIFO)、消息队列、共享内存以及信号量。这些通信方式分别具有不同的特性和应用场景,例如管道的半双工特性、FIFO的命名功能、消息队列的记录和优先级管理、共享内存的直接数据交换以及信号量的同步机制。文章还提到了多机通信中的套接字通信。
摘要由CSDN通过智能技术生成

进程间交换信息的方法---进程间通信(IPC)

IPC的方式有单机通信与多机通信(是否在同一台机子上进行通信)

单机通信:

  • 管道(包括无名管道和命名管道)
  • 半双工管道,FIFO
  • 全双工管道,命名全双工管道
  • 消息队列
  • 信号量
  • 共享存储

多机通信:

  • 套接字STREAMS
  • Socket

一:管道

通常为无名管道

特点:

  • 半双工,数据只能在一个方向上流动,有固定读端和写端
  • 只适用于有亲缘关系的进程,如父子进程与兄弟进程
  •  可以看作是一种特殊的文件,也可以使用fread和fwrite等函数进行读写,但是并不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。当进程结束之后,管道也随之消失,不储存数据

原型:

#include <unist.h>

int pipe(int fd[2]);  //返回值,成功返回1,失败返回-1

  • 当管道开启时,会创建两个文件描述符,fd[0]为读而打开,fd[1]为写而打开
  • 关闭管道只要把文件描述符关闭即可
  • 若要数据从父进程流向子进程,则要关闭父进程的读端和子进程的写端,反之则是从子进程流向父进程
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

int main()
{
	int fd[2];
	int pid;
	char buf[128];

	if(pipe(fd) == -1){
		printf("create pipe failed\n");
	}
	
	pid = fork();
	if(pid == -1){
		printf("create child failed\n");
	}
	else if(pid > 0){
		printf("this is father\n");
		close(fd[0]);  //关闭读端,开始写
		write(fd[1],"hello from father\n",strlen("hello from father\n"));
		wait();
	}
	else{
		printf("this is child\n");
		close(fd[1]);  //关闭写端,开始读
		read(fd[0],buf,128);
		printf("the message is %s\n",buf);
		exit(0);
	}	

	return 0;
	
}

二:FIFO

又称命名管道

特点:

  • FIFO可以在无关的进程之间交换数据,与无名管道不同
  • FIFO与路径名相关联,以一种特殊设备文件形式存在于文件系统中

原型:

int mkfifo(const char *pathname,mode_t mode);

mode参数与open中的mode参数使用相同 

//创建管道

#include <sys/types.h>
#include <sys/stat.h>

//       int mkfifo(const char *pathname, mode_t mode);
int main()
{
	mkfifo("./file",0600);
	return 0;
}

 

可以通过perror("why");了解失败原因

增加调试原因,避免随便报错 

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
//       int mkfifo(const char *pathname, mode_t mode);
int main()
{
	if((mkfifo("./file",0600) == -1) && errno != EEXIST){
		printf("create fifo failed\n");
	}
	
	return 0;
}

 实现两个进程间通信

//read.c

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

//       int mkfifo(const char *pathname, mode_t mode);
int main()
{
	char buf[30] = {0};
	int nread = 0;

	if((mkfifo("./file",0600) == -1) && errno != EEXIST){
		printf("create fifo failed\n");
	}
	
	int fd = open("./file",O_RDONLY);
	printf("open success\n");

	while(1){
		nread = read(fd,buf,30);
		printf("read %d byte,content: %s\n",nread,buf);
		if(nread == 3){
			break;
		}
	}

	close(fd);
	return 0;
}

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值