转载自:https://blog.csdn.net/qq_36829091/article/details/80138836
每一个进程来说这个进程看到属于它的一块内存资源,这块资源是它所独占的,所以进程之间的通信就会比较麻烦,原理就是需要让不同的进程间能够看到一份公共的资源。所以交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间 拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信。一般我们采用的进程间通信方式有:
- 管道(pipe)和有名管道(FIFO)
- 信号(signal)
- 消息队列
- 共享内存
- 信号量
- 套接字(socket)
我们先来从最简单的通信方式来说起。
匿名管道
也简称管道,
管道的创建
管道是一种最基本的进程间通信机制。管道由pipe函数来创建:
SYNOPSIS #include <unistd.h> int pipe(int pipefd[2]);
调用pipe函数,会在内核中开辟出一块缓冲区用来进行进程间通信,这块缓冲区称为管道,它有一个读端和一个写端。
pipe函数接受一个参数,是包含两个整数的数组,如果调用成功,会通过pipefd[2]传出给用户程序两个文件描述符,需要注意pipefd [0]指向管道的读端, pipefd [1]指向管道的写端,那么此时这个管道对于用户程序就是一个文件,可以通过read(pipefd [0]);或者write(pipefd [1])进行操作。pipe函数调用成功返回0,否则返回-1..
那么再来看看通过管道进行通信的步骤:
1.父进程创建管道,得到两个文件描述符指向管道的两端
2. 利用fork函数创建子进程,则子进程也得到两个文件描述符指向同一管道
3. 父进程关闭读端(pipe[0]),子进程关闭写端(pipe[1]),则此时父进程可以往管道中进行写操作,子进程可以从管道中读,从而实现了通过管道的进程间通信。
#include<stdio.h> #include<unistd.h> #include<string.h> int main() { int _pipe[2]; int ret = pipe(_pipe); if(ret < 0) { perror("pipe "); } pid_t id = fork(); if(id < 0) { perror("fork "); } else if(id == 0) { close(_pipe[0]); int i = 0; char* msg = NULL; while(i < 100) { msg = "I am child"; write(_pipe[1], msg, strlen(msg)); sleep(1); ++i; } } else { close(_pipe[1]); int i = 0; char msg[100]; while(i < 100) { memset(msg, '