前言
本文记录的是进程通信间的有名管道
一、思维导图
二、例程
1.代码
一个文件是写内容到有名管道,另外一个文件是读内容到有名管道 代码如下(示例):
mkfifo_write.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO_PATH "/tmp/myfifo"
int main(int argc, char const *argv[])
{
const char buf[20] = "hello linux!";
if( access(FIFO_PATH, F_OK) ) {
if( mkfifo(FIFO_PATH, 0666) < 0) {
perror("mkfifo error");
return -1;
} else {
printf("创建有名管道成功!\n");
}
}
int fd_fifo = open(FIFO_PATH, O_WRONLY);
if(fd_fifo < 0) {
perror("open fifo error");
return -1;
}
ssize_t ret = write (fd_fifo, buf, strlen(buf));
if(ret > 0) {
printf("成功写入%ld个字节\n", ret);
}
close(fd_fifo);
return 0;
}
mkfifo_read.c
代码如下(示例):
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO_PATH "/tmp/myfifo"
int main(int argc, char const *argv[])
{
char buf[20] = {0};
if( access(FIFO_PATH, F_OK) ) {
if( mkfifo(FIFO_PATH, 0666) < 0) {
perror("mkfifo error");
return -1;
}
}
int fd_fifo = open(FIFO_PATH, O_RDONLY);
if(fd_fifo < 0) {
perror("open fifo error");
return -1;
}
ssize_t ret = read(fd_fifo, buf, sizeof(buf));
if(ret > 0) {
printf("成功读取%ld个字节\n", ret);
printf("内容是:%s\n", buf);
}
close(fd_fifo);
return 0;
}
结果如图所示:
2.日志文件案例
思路: 服务器通过读取有名管道文件的内容,然后写入到日志文件; 客户端通过创建父子进程,然后不断往有名管道更新内容 代码如下(示例):
mkfifo_server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define FIFO_PATH "/tmp/myfifo"
#define JOURNAL_PATH "./journal.txt"
int main(int argc, char const *argv[])
{
char msg_buf[150] = {0};
if( access(FIFO_PATH, F_OK) ) {
if( mkfifo(FIFO_PATH, 0666) < 0) {
perror("mkfifo error");
return -1;
} else {
printf("创建有名管道成功!\n");
}
}
int fd_fifo = open(FIFO_PATH, O_RDONLY);
if(fd_fifo < 0) {
perror("open fifo error");
return -1;
}
int fd_file = open(JOURNAL_PATH, O_RDWR | O_CREAT, 0666);
if(fd_file < 0) {
perror("open file error");
return -1;
}
while(1) {
read(fd_fifo, msg_buf, sizeof(msg_buf));
write (fd_file, msg_buf, strlen(msg_buf));
memset(msg_buf, 0, sizeof(msg_buf));
}
close(fd_fifo);
close(fd_file);
return 0;
}
mkfifo_client.c
代码如下(示例):
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/wait.h>
#define FIFO_PATH "/tmp/myfifo"
#define FATHER_INFO "father"
#define SON_INFO "son"
int main(int argc, char const *argv[])
{
char msg_buf[150] = {0};
int status;
if( access(FIFO_PATH, F_OK) ) {
if( mkfifo(FIFO_PATH, 0666) < 0) {
perror("mkfifo error");
return -1;
} else {
printf("创建有名管道成功!\n");
}
}
int fd_fifo = open(FIFO_PATH, O_RDWR);
if(fd_fifo < 0) {
perror("open fifo error");
return -1;
}
pid_t pid = fork();
if(pid > 0) {
printf("我是父进程,ID:%d\n", getpid());
time_t tloc;
while(1) {
time(&tloc);
memset(msg_buf, 0, sizeof(msg_buf));
sprintf(msg_buf, "pid:%d\t info:%s\t time:%s\n", getpid(), FATHER_INFO, ctime(&tloc));
write (fd_fifo, msg_buf, strlen(msg_buf));
sleep(5);
}
wait(&status);
} else if(0 == pid) {
printf("我是子进程,ID:%d\n", getpid());
time_t tloc;
while(1) {
time(&tloc);
memset(msg_buf, 0, sizeof(msg_buf));
sprintf(msg_buf, "pid:%d\t info:%s\t time:%s\n", getpid(), SON_INFO, ctime(&tloc));
write (fd_fifo, msg_buf, strlen(msg_buf));
sleep(5);
}
}
close(fd_fifo);
return 0;
}
结果如图所示:
|