程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 進程間通信的方式(一):管道

進程間通信的方式(一):管道

編輯:關於C++

管道

(一).通信方式:

進程間通信又稱IPC(Inter Process Communication),它可以通過文件 管道 有名管道 共享內存 消息隊列 信號量 套接字這幾個方式進行通信,但是文件這種以及消息隊列基本已被淘汰。

所以常用的通信方式有:

1.管道

2.信號

3.共享映射區

4.本地套接字

(二).管道基本概念:

而其中的管道機制,是屬於最簡單的一種通信方式。它適用於有血緣關系的進程之間的單向通信。它的本質是偽文件,是一段內核緩沖區。實現原理是內核使用環形隊列,借助內核緩沖區實現。

當我們調用pipe()函數創建管道時,需要傳入一個文件描述符數組,一個表示讀端,一個表示寫端。就好像一個管道一樣,寫方進程將數據寫入,讀方再通過管道將數據讀出。既然規定了讀和寫的兩端,以及是環形隊列以及緩沖區實現,就證明了有一定的局限性。

1.數據不可反復讀取,即讀了之後在緩沖區中就沒有了

2.半雙工通信,只能單方向的傳輸數據

3.有血緣關系的進程之間通信

(三).使用管道進行通信:

創建管道的函數原型:int pipe(pipefd[2])

所需頭文件:#include

參數pipefd[2]會返回兩個文件描述符,一個用於讀,另一個用於寫。默認是fd[0]讀,fd[1]寫。如果創建管道成功,返回0,否則返回-1。

例子:

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

int main()
{
    int fd[2];
    pid_t pid;

    if(pipe(fd) == -1)
    {
        perror("pipe error:");
        exit(1);
    }

    pid = fork();
    if(pid == -1)
    {
        perror("fork error:");
        exit(2);
    }
    else if(pid == 0) //本例子中子進程寫數據
    {
        close(fd[0]); //關閉讀數據的文件描述符
        write(fd[1], "hello pipe!\n", strlen("hello pipe!\n")); //寫入數據
    }
    else
    {
        close(fd[1]);
        char buf[102400];
        int ret = read(fd[0], buf, sizeof(buf)); //通過管道讀出數據
        if(ret == 0)
        {
            printf("讀到了文件末尾\n");
        }
        write(STDOUT_FILENO, buf, ret);  //輸出到終端
    }
    return 0;
}
//輸出結果:
hello pipe!
(五).注意事項:

在使用管道時,有幾種特殊情況需要注意:

1.管道中沒有數據時,如果管道寫端全部關閉,那麼此時read函數會返回0,如果管道寫端沒有全部關閉,那麼此時read會阻塞等待數據。也就是說,在上面的例子中,如果子進程通過sleep函數睡眠10秒,父進程也會阻塞等待子進程寫數據,因為此時子進程的寫端仍處於開啟狀態。

2.管道讀端全部關閉,進程會異常終止(可以理解為讀數據的都沒有了,那寫數據也沒有意義了)

3.管道已滿時,寫入會阻塞。

要知道管道只能在有血緣關系的進程之間通信,而有名管道恰可以用於無血緣關系的進程間通信。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved