有名管道实现进程间的对话

有名管道是进程间通信的一种方式。要实现进程间的对话,我们先要设置一个server进程, 它负责创建有名管道,实现发送信息和获取信息。

server端的代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PIPE_ONE "/tmp/serverRecive"
#define PIPE_TWO "/tmp/serverSend"

int main(void) {
    int res = 0;
    int pipe_one = -1;
    int pipe_two = -1;
    char reciveMsg[PIPE_BUF + 1] = {0};
    char sendMsg[PIPE_BUF + 1] = {0};

    if(access(PIPE_ONE, F_OK)) {    // 如果没有该文件,access函数返回-1
        res = mkfifo(PIPE_ONE, 0777);   // 如果正常创建, 则返回0

        if(-1 == res) {
            fprintf(stderr, "进程:%d, 第一条管道建立失败", getpid());
            exit(1);
        }
    }

    if(access(PIPE_TWO, F_OK)) {
        res = mkfifo(PIPE_TWO, 0777);   // 如果正常创建, 则返回0

        if(-1 == res) {
            fprintf(stderr, "进程:%d, 第二条管道建立失败", getpid());
            exit(1);
        }
    }

    printf("进程:%d 正在打开pipe_one pipe_two\n", getpid());
    pipe_one = open(PIPE_ONE, O_RDONLY);
    pipe_two = open(PIPE_TWO, O_WRONLY);
    if(-1 == pipe_one) {
        fprintf(stderr, "进程:%d 打开pipe_one时出错\n", getpid());
        exit(1);
    }
    if(-1 == pipe_two) {
        fprintf(stderr, "进程:%d 打开pipe_two时出错\n", getpid());
        exit(1);
    }
    printf("进程:%d 打开了pipe_one pipe_two\n", getpid());

    gets(sendMsg);
    write(pipe_two, sendMsg, strlen(sendMsg));
    reciveMsg[read(pipe_one, reciveMsg, PIPE_BUF)] = '\0';
    puts(reciveMsg);



    return 0;
}
  • 首先,我们先用access函数来检测管道是否已经存在了, 如果access返回值为-1, 则表明需要创建管道,我们使用mkfifo函数来创建管道。如果access返回值为0,则表明管道已经存在,我们不需要再创建了。
  • 接下来,server打开两个管道的读端和写端。如果open函数的返回值为-1,则表明没有正常的打开管道。
  • 最后,我们通过write函数来写信息,用read函数来读信息。 实现server端的读和写。

因为client函数不需要去创建管道,因此它的代码能够简短一些。

client端的代码如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PIPE_ONE "/tmp/serverRecive"
#define PIPE_TWO "/tmp/serverSend"

int main(void) {
    int res = 0;
    int pipe_one = -1;
    int pipe_two = -1;
    char reciveMsg[PIPE_BUF + 1] = {0};
    char sendMsg[PIPE_BUF + 1] = {0};

    printf("进程:%d 正在打开pipe_one pipe_two\n", getpid());
    pipe_one = open(PIPE_ONE, O_WRONLY);
    pipe_two = open(PIPE_TWO, O_RDONLY);
    if(-1 == pipe_one) {
        fprintf(stderr, "进程:%d 打开pipe_one时出错\n", getpid());
        exit(1);
    }
    if(-1 == pipe_two) {
        fprintf(stderr, "进程:%d 打开pipe_two时出错\n", getpid());
        exit(1);
    }
    printf("进程:%d 打开了pipe_one和pipe_two\n", getpid());

    reciveMsg[read(pipe_two, reciveMsg, PIPE_BUF)] = '\0';
    puts(reciveMsg);
    gets(sendMsg);
    write(pipe_one, sendMsg, strlen(sendMsg));



    return 0;
}

client值得注意的地方是, 它的读端和写端刚好server的相反。其他部分和server的没什么区别。

注意:在这两个程序中,有一处阻塞值得注意:
open函数阻塞:只有当一个管道的读端和写端同时被打开, 程序才会继续往下运行。如图,server一直在阻塞,等待client打开管道

你可能感兴趣的:(有名管道实现进程间的对话)