進程間通信——管道

基於管道的進程間通信模型

管道通信模型

爲了完成進程間通信,需要先建立管道。管道不屬於進程的資源而是和套接字一樣屬於操作系統。兩個進程通過操作系統提供的內存空間進行通信。

創建管道的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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章