Linux学习笔记-对父子进程直接通信基础与实例

140 篇文章 11 订阅

目录

原理

栗子


原理

实现进程通信的目的:

数据传输!
共享数据!
通知事件!
资源共享!
进程控制!

早期linux进程间信号(IPC)有3个部分:

  1. UNIX进行通信方式:管道、FIFO、信号;
  2. System V进程通信: System V消息队列、System V信号量、 System V共享内存;
  3. POSIX进程间通信:posix消息队列、posix信号量、posix共享内存;

目前Linux进程通信方式:

  1. 管道(pipe)和命名管道(FIFO);
  2. 信号(signal);
  3. 消息队列;
  4. 共享内存;
  5. 信号量;
  6. 套接字(socket);


管道通信:

  1. 本地计算机的两个进程之间的通信而设计的,管道建立后,获取两个文件的描述符:一个用于写,一个用于读;
  2. 通过pipe系统调用;
  3. 管道是单工的,数据只向一个方向流动,双向流动要建立两个管道;
  4. 数据的读出和写入:一个进程向管道中写的内容被管道另一端读出。写入的内容每次都添加到管道的缓存区的末尾,并且每次都是从缓存区的头部读取数据。

【注意:管道实际上是创建到计算机内核当中的缓存】

管道分类:
匿名管道:

  1. 在关系进程中进行(父进程和子进程、兄弟进程直接);
  2. 由pipe系统调用,管道由父进程建立;
  3. 管道位于内核空间,其实是一块缓存;

命名管道(FIFO):

  1. 两个进程之间没有任何关系,本质上是内核中的一块缓存,另外在文件系统中以一个特殊的设备文件(管道文件)存在。
  2. 通过系统调用mkfifo创建;

【注意可以通过操作这个管道文件就可以了,他会自动同步到缓存中】

注意:
fork子进程后,会复制父进程的数据(代码段,数据段,堆栈等),所以fd(文件描述符)也会被复制
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。

 

栗子

下面是源码,要注意:

  1. fd[0]:为pipe的读端口;fd[1]:为pipe的写端口;
  2. 要注意,用完,或不用端口就把他关掉;
  3. 父进程要回收下子进程、wait()是等待进程结束;

源码如下:

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main(void){

	int fd[2];

	if(pipe(fd) < 0){
		
		perror("pipe error!");
		exit(1);
	}

	pid_t pid;	
	if((pid = fork()) < 0){
		
		perror("fork error");
		exit(1);
	}
	else if(pid >0 ){	// parent process
	
		close(fd[0]);
		int start = 1, end = 100;

		//往管道中写数据
		if(write(fd[1], &start, sizeof(int)) != sizeof(int)){
			
			perror("write error");
			exit(1);			
		}
		if(write(fd[1], &end, sizeof(int)) != sizeof(int)){
		
			perror("write error");
			exit(1);
		}
		close(fd[1]);
		wait(0);
	}
	else{			//child process

		close(fd[1]);
		int start, end;
		if(read(fd[0], &start, sizeof(int)) < 0){

			perror("read error");
			exit(1);
		}
		if(read(fd[0], &end, sizeof(int)) < 0){
			
			perror("read error");
			exit(1);
		}
		close(fd[0]);
		printf("child process read start: %d , end: %d \n", start, end);
	}

	exit(0);
}

程序运行截图如下:

### 回答1: Linux父子进程通信可以使用以下几种方法: 1. 管道(pipe) 2. 信号(signal) 3. 共享内存(shared memory) 4. 消息队列(message queue) 5. 信号量(semaphore) 6. 套接字(socket) ### 回答2: 在Linux系统中,进程不仅可以与其他进程进行通信,还可以与其父子进程进行通信父子进程是指一个进程可以通过fork调用创建一个新的进程,其中原进程为父进程,新进程子进程父子进程之间的通信主要是通过管道来实现的。 所谓管道,就是一个数据通道,可以使得数据从一个进程流入到另一个进程中。在Linux系统中,管道主要有两种类型:匿名管道和命名管道。匿名管道是指在进程之间创建的一种特殊文件,它没有文件名,只能用于父进程和其子进程之间的通信。而命名管道也叫有名管道,是一种系统级的FIFO文件,可用于任意进程间的通信。 在Linux系统中,父进程子进程之间通信的一般步骤如下: 1. 创建一个管道,使用pipe()函数。 2. 创建子进程,使用fork()函数。 3. 在子进程中,关闭管道的写入端,即用close()函数关闭fd[1]。 4. 在父进程中,关闭管道的读取端,即用close()函数关闭fd[0]。 5. 父进程向管道中写入数据,使用write()函数将数据写入fd[1]。 6. 子进程从管道中读取数据,使用read()函数从fd[0]中读取数据。 7. 父进程子进程需要在完成通信后关闭管道,即分别使用close()函数关闭fd[0]和fd[1]。 父子进程之间的通信可以用于各种场景下,例如:进程间传递数据、子进程返回值给父进程、父进程传递命令给子进程等等。总之,在Linux系统中,管道是一种很有用的进程通信方法,能够使得父子进程之间的通信变得轻松简单,而且无需使用外部的库或工具。 ### 回答3: Linux是一种使用广泛的操作系统,其优势之一是其提供了多种通信机制,包括父子进程通信父子进程间的通信Linux进程通信的一种常见方式。 在Linux中,通过fork()系统调用可以实现父进程创建子进程。在子进程中,可以使用exec函数进行新程序的加载。父子进程之间通过进程标识符(PID)进行通信,父进程子进程拥有各自独立的地址空间和文件描述符表。 父进程可以通过创建匿名管道或命名管道来向子进程发送数据,也可以通过IPC通信、共享内存等方式进行通信。当父子进程同时访问共享资源时,需要使用信号量或互斥锁等同步机制进行互斥。 子进程可以通过exit()函数向父进程发送退出信号。子进程也可以使用SIGCHILD信号告知父进程它的状态发生了变化。 在使用父子进程通信时,需要注意的是,由于父子进程之间的关系是一一对应的,因此如果有多个子进程需要与父进程进行通信,则需要针对每个子进程分别进行通信处理。 总之,Linux父子进程通信是非常有用的一种进程通信方式,既可以实现单一方向的通信,也可以实现双向通信,非常适合在多进程程序中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT1995

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

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

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

打赏作者

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

抵扣说明:

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

余额充值