进程间通信之命名管道

与匿名管道相比,命名管道通信的两个进程可以脱离父子关系。即任意两个进程都能通过该方式通信。
测试代码如下。

  • 发送端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <signal.h>

/** 
 * cmd: mkfifo - make FIFOs(named pipes)
 * eg.  mkfifo namedpipe
 *      echo "I am testing pipe" > namedpipe &
 */

#define PIPENAME    "./myfifo"
#define BUFFSIZE    128

int main(int argc, char *argv[])
{
    int fd = -1;
    unsigned char buff[BUFFSIZE] = {0};
    int count = 0;

    /** Create a named pipe, if pipe already exists, skip this step */
    if(0 != mkfifo(PIPENAME, 0666) && errno != 17)
    {
        perror("Create named pipe failed");
        return -1;
    }

    /** Open pipe with block mode, add O_NONBLOCK flag to open with unblock mode */
    if((fd = open(PIPENAME, O_WRONLY)) < 0)
    {
        perror("Open namedpipe failed");
        return -1;
    }

    /** Ignore SIGPIPE signal to prevent sending end process crash */
    signal(SIGPIPE, SIG_IGN);

    while(1)
    {
        memset(buff, 0, sizeof(buff));
        sprintf(buff, "Hello-%d", ++count);
        if(-1 != write(fd, buff, BUFFSIZE))
        {
           printf("Send:%s\n", buff);
        }
        sleep(1);
    }

    return 0;
}
  • 接收端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

#define PIPENAME    "./myfifo"
#define BUFFSIZE    128

int main(int argc, char *argv[])
{
    int fd = -1;
    unsigned char buff[BUFFSIZE] = {0};
    pid_t pid;
    int count = 0;

    while(1)
    {
        if((fd = open(PIPENAME, O_RDONLY)) < 0 && errno == 2)
        {
            perror("Open namedpipe failed");
            sleep(1);
        }
        else
        {
            break;
        }
    }

    pid = getpid();
    while(1)
    {
        memset(buff, 0, sizeof(buff));
        if(0 < read(fd, buff, BUFFSIZE))
        {
            printf("[%d]Recv[%d]:%s\n", pid, ++count, buff);
        }
        sleep(1);
    }

    return 0;
}

注意:
在测试过程中发现,在通信过程中,如果终止接收端进程则会导致发送端进程意外退出。经了解,发送端意外退出的原因是接收端进程终止时,发送端进程会收到一个SIGPIPE信号,导致进程终止。可以将该信号忽略防止发送端意外终止。

posted on 2022-08-26 14:10  OrangeGLC  阅读(54)  评论(0)    收藏  举报

导航