进程间通信之命名管道
与匿名管道相比,命名管道通信的两个进程可以脱离父子关系。即任意两个进程都能通过该方式通信。
测试代码如下。
- 发送端
#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信号,导致进程终止。可以将该信号忽略防止发送端意外终止。
浙公网安备 33010602011771号