系統(tǒng)編程-------進程間通訊

進程間通訊

pipe, 親屬間進程通訊,

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

參數(shù):

  • pipedfd :用于接收pipe函數(shù)創(chuàng)建的管道文件的讀寫文件描述
  • pipefd[0] :指向管道文件的讀端
  • pipefd[1]:指向文件寫端

返回值:成功腺律,返回0;失敗返回1贷腕;

mkfifo ,任意進程之間通訊

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

參數(shù):

  • const char *pathname蜜另;管道文件

  • mode_t mode 文件權限

    ?

//親屬進程間的通訊
#include <stdio.h>
#include <unistd.h>

#define BUFFER_SIZE 1024

// int pipe(int pipefds[2]);
// 參數(shù):
//      pipefds 用于接收pipe函數(shù)創(chuàng)建的管道文件的讀寫文件描述符
//      pipefds[0]      指向管道文件的讀端
//      pipefds[1]      指向管道文件的寫端
// 返回值:成功返回0,失敗等缀,返回-1

int main(int argc, char *argv[])
{
    pid_t child_pid = 0;
    int pipe_fds[2] = {0};
    char buf[BUFFER_SIZE] = {'\0'};
    
    // 創(chuàng)建pipe
    if(pipe(pipe_fds) == -1)
    {
        perror("pipe failed");
        return 1;
    }
    
    // 數(shù)據(jù)從子進程傳遞給父進程
    if((child_pid = fork()) == 0)
    {
        int n = 0;
        // child process
        // 1.關閉子進程中管道的讀文件描述符
        close(pipe_fds[0]);
        while(1)
        {
            // 2.從標準輸入文件中讀入數(shù)據(jù)
            n = read(STDIN_FILENO, buf, BUFFER_SIZE);   
            // 3.將讀到的數(shù)據(jù)寫入到管道中
            write(pipe_fds[1], buf, n);
        }
    }
    else if(child_pid > 0)
    {
        int n =0;
        // parent process
        // 1.在父進程中關閉管道的寫文件描述符
        close(pipe_fds[1]);
        while(1)
        {
            // 2.從管道中讀取數(shù)據(jù)
            n = read(pipe_fds[0], buf, BUFFER_SIZE);
            // 3.將從管道中讀取的數(shù)據(jù)寫入到標準輸出文件
            write(STDOUT_FILENO, buf, n);
        }
    }
    else
    {
        // error
    }

    return 0;
}
    

任意兩個進程間的通訊:

實例一:

//寫管道程序**********************************************
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int n = 0;
    char buf[1024] = {'\0'};
    int fd = 0;

    // 判斷有名管道文件是否村子蜂绎,不存在則創(chuàng)建
    if(access("test_file.fifo", F_OK) != 0 )
    {
        mkfifo("test_file.fifo", 
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }

    // 1.打開管道文件
    if((fd = open("test_file.fifo", O_WRONLY)) == -1)
    {
        perror("open failed");
        return 1;
    }

    printf("waiting for input data...\n");
    while(1)
    {
        // 2.從標準輸入文件中讀入數(shù)據(jù)
        n = read(STDIN_FILENO, buf, 1024);
        // 3.將讀到的數(shù)據(jù)寫入到管道文件中
        write(fd, buf, n);
    }
    
    printf("writer process exit...\n");
    
    return 0;
}
//讀管道程序*************************************************
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>

int main(int argc, char *argv[])
{
    int n = 0;
    char buf[1024] = {'\0'};
    int fd = 0;
    
    // 判斷管道文件是否存在搓逾,不存在則創(chuàng)建
    if(access("test_file.fifo", F_OK) != 0 )
    {
        mkfifo("test_file.fifo", 
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }
    
    // 1.打開管道文件
    fd = open("test_file.fifo", O_RDONLY);
    if(fd == -1)
    {
        perror("open failed");
        return 1;
    }
    
    printf("waiting for read data...\n");
    // 2.從管道文件中讀取數(shù)據(jù)
    while((n = read(fd, buf, 1024)) > 0)
    {
        // 3.將讀到的數(shù)據(jù)寫入到標準輸出文件中
        write(STDOUT_FILENO, buf, n);
    }
    
    printf("reader process exit...\n");
    
    return 0;
}

實例二:

簡易聊天程序

// ./named-pipe-chat  user_name

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

// 用戶名的最大長度
#define USER_NAME_MAX_LEN 100
// 發(fā)送消息文本的最大長度
#define MSG_MAX_LEN 500
// 文件名的最大長度
#define FILE_NAME_MAX_LEN 100

// 聊天消息結構體類型
struct msg_node 
{
    // 發(fā)送消息用戶名
    char src_username[USER_NAME_MAX_LEN];
    // 接收消息用戶名
    char dst_username[USER_NAME_MAX_LEN];
    // 消息文本
    char text[MSG_MAX_LEN];
};

int main(int argc, char *argv[])
{
    // 判斷命令行參數(shù)是否滿足條件
    if(argc != 2)
    {
        printf("usage : %s <username>\n", argv[0]);
        return 1;
    }

    // 子進程ID
    pid_t child_pid;
    // 登陸用戶的命令管道文件名
    char filename[FILE_NAME_MAX_LEN] = {'\0'};

    // 構造登陸用戶的命令管道文件名,并判定用戶是否存在
    sprintf(filename, "%s.fifo", argv[1]);
    if(access(filename, F_OK) != 0)
    {
        mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    }

    // 創(chuàng)建子進程
    if((child_pid = fork()) == 0)       // 子進程中執(zhí)行的代碼骗露,子進程負責接收其他用戶發(fā)送的消息并打印顯示
    {
        int n = 0;
        struct msg_node msg;
        int fd = 0;
        
        // 1.打開登陸用戶的管道文件岭佳,用于接收其他用戶發(fā)送的消息數(shù)據(jù)結構體
        if((fd = open(filename, O_RDONLY)) == -1)
        {
            perror("open failed");
            return 1;
        }
        // 2.循環(huán)的從管道文件中讀入消息信息,并打印顯示
        while((n = read(fd, &msg, sizeof(msg))) > 0)
        {
            printf("%s ----> %s : %s\n",
                msg.src_username, msg.dst_username, msg.text);
        }
        
        // 3.關閉管道文件
        close(fd);
    }
    else if(child_pid > 0)          // 父進程萧锉,負責從鍵盤讀入相關數(shù)據(jù)珊随,寫入執(zhí)行用戶的管道文件
    {
        struct msg_node msg;
        int fd = 0;
        // 接收用戶的管道文件名
        char dst_filename[FILE_NAME_MAX_LEN] = {'\0'};
        
        // 發(fā)送者永遠為當前登錄用戶
        strcpy(msg.src_username, argv[1]);
        
        // 1.輸入接收消息的用戶名名稱
        printf("to>");
        fgets(&msg.dst_username, USER_NAME_MAX_LEN, stdin);
        // 1.1將用戶名末尾的'\n'替換為'\0'
        msg.dst_username[strlen(msg.dst_username)-1] = '\0';
        
        // 1.3構造接收用戶的管道文件名
        sprintf(dst_filename, "%s.fifo", msg.dst_username);
        // 1.3打開管道文件
        if((fd = open(dst_filename, O_WRONLY)) == -1)
        {
            perror("open failed");
            return 1;
        }
        
        // 循環(huán)的發(fā)送從鍵盤讀入的數(shù)據(jù)
        while(1)
        {
            // 2.輸入待發(fā)送的消息字符串
            printf("text>");
            fgets(&msg.text, MSG_MAX_LEN, stdin);
            // 2.2將消息文本末尾的'\n'替換為'\0'
            msg.text[strlen(msg.text)-1] = '\0';
            
            // 3.將構造的消息結構體寫入管道文件
            write(fd, &msg, sizeof(msg));
        }
        // 3.3close
        close(fd);
    }
    else
    {
    }
    
    // 刪除登陸用戶的管道文件
    remove(filename);

    return 0;
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柿隙,隨后出現(xiàn)的幾起案子叶洞,更是在濱河造成了極大的恐慌,老刑警劉巖禀崖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衩辟,死亡現(xiàn)場離奇詭異,居然都是意外死亡波附,警方通過查閱死者的電腦和手機艺晴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掸屡,“玉大人封寞,你說我怎么就攤上這事〗霾疲” “怎么了狈究?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長盏求。 經(jīng)常有香客問我抖锥,道長亿眠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任宁改,我火速辦了婚禮缕探,結果婚禮上魂莫,老公的妹妹穿的比我還像新娘还蹲。我一直安慰自己,他們只是感情好耙考,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布谜喊。 她就那樣靜靜地躺著,像睡著了一般倦始。 火紅的嫁衣襯著肌膚如雪斗遏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天鞋邑,我揣著相機與錄音诵次,去河邊找鬼。 笑死枚碗,一個胖子當著我的面吹牛逾一,可吹牛的內容都是我干的。 我是一名探鬼主播肮雨,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼遵堵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了怨规?” 一聲冷哼從身側響起陌宿,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎波丰,沒想到半個月后壳坪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡掰烟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年爽蝴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片媚赖。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡霜瘪,死狀恐怖,靈堂內的尸體忽然破棺而出惧磺,到底是詐尸還是另有隱情颖对,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布磨隘,位于F島的核電站缤底,受9級特大地震影響顾患,放射性物質發(fā)生泄漏。R本人自食惡果不足惜个唧,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一江解、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧徙歼,春花似錦犁河、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酿秸,卻和暖如春灭翔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辣苏。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工肝箱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稀蟋。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓煌张,卻偏偏與公主長得像,于是被迫代替她去往敵國和親糊治。 傳聞我的和親對象是個殘疾皇子唱矛,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內容

  • 進程間通信 進程間通信即IPC(InerProcess Communication)Unix ipc 已經(jīng)是而且繼...
    千里山南閱讀 457評論 0 2
  • 一.管道機制(pipe) 1.Linux的fork操作 在計算機領域中,尤其是Unix及類Unix系統(tǒng)操作系統(tǒng)中井辜,...
    Geeks_Liu閱讀 3,685評論 1 9
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,757評論 25 707
  • 我認識姑娘不超過3個時15分零8秒粥脚,和姑娘說過的話不超過26個字窃肠,但是當姑娘疲憊歪著頭不小心靠到我的肩膀時刷允,有一種...
    夢小言閱讀 394評論 3 3
  • 從那刻起 我的世界只剩下黑白 線條交錯爬行 筆下 盡是些生活的滋味 但這生活 卻也索然無味 如白開水一般 因為 少...
    寫廢紙的熊閱讀 541評論 0 5