Head First C 第十章 進程間通訊 建立管道

Head First C 第十章 進程間通訊 建立管道

咱們已經能夠經過重定向的方式,將子進程的輸出重定向到文件,但咱們想從進程中直接讀取數據,如何使實現。python

用管道鏈接進程

咱們曾經用一個命令來鏈接進程,那就是管道:git

  • python fake_rss.py | grep 'naruto'

能夠用管道把一個進程的輸出鏈接到另外一個進程的輸入。 管道兩側的命令是父子關係。github

  1. 命令行建立了父進程。
  2. 父進程在子進程中克隆出了fake_rss.py腳本。
  3. 父進程用管道把子進程的輸出鏈接到本身的輸入。
  4. 父進程運行grep命令。

若是想在c代碼中,而不是命令行中實現管道鏈接,該怎麼作呢。數組

在瀏覽器中打開連接

咱們要作如下兩件事:瀏覽器

  1. 從python腳本的輸出中獲取連接
  2. 在瀏覽器中打開連接
如何建立管道

咱們要在進程中建立兩條新的流,用於管道的讀取與寫入。函數

數據流
0 stdin
1 stdout
2 stderr
3 管道讀取端
4 管道寫入端
  1. pipe()函數創建管道 由於子進程要把數據發送到父進程裏,因此要用管道鏈接子進程的標準輸入父進程的標準輸出。 咱們說過,每當打開數據流時,它都會加入描述符表。pipe()函數也是如此,它建立兩條相連的數據流,並把它們加入描述符表中。 這樣你只要從一條數據流中寫入數據,就能從另外一條數據流中讀取
  2. 描述符存放在一個包含兩個元素的數組中
    int fd[2];
    	if (pipe(fd) == -1) {
    	    error("Can't create pipe");
    	}
  3. fd[1]寫管道,fd[0]讀管道 1. 在子進程中: - 須要關閉管道的fd[0]端 - 修改子進程的標準輸出,讓它指向fd[1]對應的數據流 由於子進程不會從管道中讀取數據,子進程發送給標準輸出的數據都會寫入到管道中。 2. 在父進程中: - 須要關閉管道的fd[1]端,由於父進程不須要往管道中寫入數據 - 修改父進程的標準輸入,使其從描述符fd[0]的數據流中讀取數據。
使用管道進行進程間通訊
  1. 對於子進程的操做
    if (pid == 0) {
    
        dup2(fd[1], 1);
        close(fd[0]);
        execlp("python", "python", "./fake_rss.py", NULL);

} 2. 父進程的操做c dup2(fd[0], 0); close(fd[1]); char line[255]; while (fgets(line, sizeof(line) / sizeof(char), stdin)) { if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = 0; printf("Got url :%s\n", line);url

pid_t pid2 = fork();
if (pid2 == 0) {
  open_url(line);
}

} ``` 父進程要作的是: 1. 將標準輸入stdin重定向到*fd[0]*的數據流。 2. 用一個while循環從stdin讀入數據,判斷條件爲讀入的結果(當執行腳本結束時會返回EOF,fgets()返回0,循環結束)。 3. 再fork()一次,用於建立多個子進程打開多個url。命令行

有名管道

有名管道是基於文件的管道,也叫作FIFO(First In First Out)文件。 由於基於文件的管道有名字,因此兩個進程只要知道管道的名字就能用它來通訊,即便它們不是父子進程。 使用系統調用mkfifo()能夠建立有名管道。code

代碼

process communication with pipe進程

相關文章
相關標籤/搜索