APUE讀書筆記-第十五章-進程間通信

管道

創建管道(pipe函數)

#include <unistd.h>
int pipe(int fd[2);

fd[0]爲讀打開,fd[1]爲寫打開

侷限性

(1)管道是半雙工的,數據只能向一個方向流動
(2)只能用於具有親緣關係的進程之間
(3)沒有名字
(4)管道的緩衝區是有限的,由常量PIPE_BUF定義
(5)管道所傳送的是無格式字節流,這就要求管道的讀出方和寫入方必須事先約定好數據的格式

管道實現進程同步的五個函數

TELL_WAIT、TELL_PARENT、TELL_CHILD、WAIT_PARENT、WAIT_CHILD

#include "apue.h"

static int  pfd1[2], pfd2[2];

void
TELL_WAIT(void)
{
    if (pipe(pfd1) < 0 || pipe(pfd2) < 0)
        err_sys("pipe error");
}

void
TELL_PARENT(pid_t pid)
{
    if (write(pfd2[1], "c", 1) != 1)
        err_sys("write error");
}

void
WAIT_PARENT(void)
{
    char    c;

    if (read(pfd1[0], &c, 1) != 1)
        err_sys("read error");

    if (c != 'p')
        err_quit("WAIT_PARENT: incorrect data");
}

void
TELL_CHILD(pid_t pid)
{
    if (write(pfd1[1], "p", 1) != 1)
        err_sys("write error");
}

void
WAIT_CHILD(void)
{
    char    c;

    if (read(pfd2[0], &c, 1) != 1)
        err_sys("read error");

    if (c != 'c')
        err_quit("WAIT_CHILD: incorrect data");
}

函數popen和pclose

創建一個管道,fork一個子進程,關閉未使用的管道端,執行一個shell命令,然後等待命令終止

#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *fp);

函數popen先執行fork,然後調用exec執行cmdstring,並且返回一個標準I/O文件指針。
如果type是“r”,則文件指針連接到cmdstring的標準輸出
如果type是“w”,則文件指針連接到cmdstring的標準輸入

協同進程

一個過濾程序既產生某個過濾程序的輸入,又讀取該過濾程序的輸出,該過濾進程就變成了協同進程

FIFO

創建FIFO

#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);

命名管道需要用open打開,在open時,用O_NONBLOCK 標誌表示非阻塞

兩種用途
(1)shell命令使用FIFO將數據從一條管道傳送到另一條時,無需創建中間臨時文件
(2)客戶進程-服務器進程應用程序中,FIFO用於匯聚點,在客戶進程和服務器進程二者之間傳遞數據

命名管道以FIFO的文件形式存在於文件系統中
不相關的進程也能夠彼此通過FIFO交換數據
FIFO嚴格遵循先進先出(first in first out),對管道及FIFO的讀總是從開始處返回數據,對它們的寫則把數據添加到末尾。它們不支持諸如lseek()等文件定位操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章