基於管道的進程間通信模型
爲了完成進程間通信,需要先建立管道。管道不屬於進程的資源而是和套接字一樣屬於操作系統。兩個進程通過操作系統提供的內存空間進行通信。
創建管道的API:
#include <unistd.h>
//成功返回 0,失敗返回 -1
int pipe(int filedes[2]);
接口參數爲文件描述符組成的數組。filedes[0]管道出口,filedes[1]管道入口。
進程間通關管道簡單通信示例:
#include <unistd.h>
#include <stdio.h>
int main()
{
int fds[2];
char str[] = "How are you!";
char buff[128] = {0};
pid_t pid;
//創建通信管道
if(pipe(fds) == -1)
{
printf("Error pipe!\n");
return 0;
}
pid = fork();
if(pid == 0)
{
//子進程向管道寫數據
write(fds[1], str, sizeof(str));
}
else
{
//父進程從管道讀數據
read(fds[0], buff, 128);
puts(buff);
}
return 0;
}
子進程拿到fds[1]向裏面寫數據,父進程拿到fds[0]從裏面讀數據,模型就像下圖這樣:
需要注意的是管道中的數據是無主的。也就說任何進程拿到了fds[0]都可以從裏面讀數據;任何進程拿到了fds[1],都可以向裏面寫數據。模型如下圖:
這個模型下是保證不了消息的屬主的,子進程可能讀到的是自己放入管道的消息,也可能是父進程放入管道的消息;父進程亦然。
如果要保證全雙工通信,則必須用兩個管道,模型如下:
#include <stdio.h>
#include <unistd.h>
int main()
{
int fds1[2];
int fds2[2];
char pstr[] = "Parant process sends message!\n";
char cstr[] = "Child process sends message!\n";
char buff[32] = {0};
if(pipe(fds1) == 0 && pipe(fds1) == 0)
{
}
else
{
printf("Error pipe(fds)!\n");
return 0;
}
pid_t pid;
pid = fork();
if(pid == 0)//子進程 用 fds[1]寫,用fds1[0]讀。父進程用fds1[1]寫,用fds2[0]讀。
{
write(fds1[1], cstr, sizeof(cstr));
//sleep(1);
read(fds2[0], buff, sizeof(buff));
puts(buff);
}
else
{
read(fds1[0], buff, sizeof(buff));
puts(buff);
write(fds2[1], pstr, sizeof(cstr));
sleep(3);
}
return 0;
}