在操作系统中,进程是独立运行的程序,多个进程之间要想互相协作完成任务,就需要进程间通信。
为了实现资源的共享,协作和同步,从而提高系统的效率和可靠性。
1.管道
2.System V
3.POSIX V
进程间通信的本质是实现资源的共享,那么最重要的一点就是如何看到同一份资源。
先聊一聊匿名管道,匿名管道是通过父子进程后,写时拷贝后,看到的同一份资源,然后让父进程关闭读端,子进程关闭写端,这样就可以让两个进程看到同一份资源了。
以前说过,每一个进程都有一个PCB,而每个PCB结构体中都有一个指针指向了struct file*struct,这个结构体里面就有文件描述符表,每一个文件描述表中的指针指向了每个文件。

所以父子进程通过fork后,就看到了同一份资源,如下图所示,又因为管道是单向的,关闭对应的读写端,就实现了通信。


成功返回0,失败返回-1,错误码被设置。pipefd是输出型参数,期望调用它,可以得到被打开的文件的fd。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
char buffer[1024*8];
int main()
{
//创建管道
int pipefd[2] = {0};
int ret = pipe(pipefd);
assert(ret != -1);
(void)ret;
pid_t id = fork();
assert(id != -1);
if(id == 0)
{
//child
//子进程去读,关闭写端
close(pipefd[1]);
// char buffer[1024*8];
while(true)
{
//s == 0 是读到了文件末尾
// s > 0 说明在有数据,还在读取
ssize_t s = read(pipefd[0],buffer,sizeof(buffer));
if(s > 0)
{
buffer[s] = 0;
cout << "child get a message[" << getpid() << "] Father# " << buffer << endl;
}
else if(s == 0)
{
cout << "write quit(father),me quit!" << endl;
exit(2);
}
}
}
//father
//关闭读端
close(pipefd[0]);
string message = "我是父进程,我正在给你发信息";
int count = 0;
// char send_buffer[1024*8];
while(true)
{
snprintf(buffer,sizeof(buffer),"%s[%d] : %d",message.c_str(),getpid(),count++);
//向send_buffer中写入
write(pipefd[1],buffer,strlen(buffer));
sleep(1);
//cout << count << endl;
if(count == 5)
{
cout << "writer quit(father)" << endl;
break;
}
}
close(pipefd[1]);
pid_t n = waitpid(id,nullptr,0);
cout << "id : " << id << " "<< "n : " << n << endl;//这里pid结果一样,说明通信成功
assert(n > 0);
(void)n;
return 0;
}
实验现象: 父进程向管道里面写入,子进程读,当5s后,关闭管道。