mkfifo
创建一个有名管道
头文件:
#include <sys/types.h>
#include <sys/stat.h>
原型:
int mkfifo(const char *pathname, mode_t mode);
参数:
char *pathname:指定要创建的fifo文件路径及文件名;
mode_t mode:有名管道的权限,(mode & ~umask);
返回值:
成功,返回0;
失败,返回-1,更新errno;如果有名管道已经存在,设置errno == EEXIST;
例程:
if(mkfifo("./myfifo", 0664) < 0)
{
if(errno != EEXIST)
{
perror("mkfifo");
return -1;
}
}
printf("创建成功\n");
open
打开有名管道
头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
原型:
int open(const char *pathname, int flags);
参数:
char *pathname:指定要打开的fifo文件路径及文件名;
int flags:指定打开文件的方式:
O_RDONLY 只读;阻塞,直到另外一个进程以写的方式打开同一个FIFO文件;
O_WRONLY 只写;阻塞,直到另外一个进程以读的方式打开同一个FIFO文件;
O_RDWR 读写;立即返回,不会阻塞;
------以上三种必须包含一种------
--前两项可(或)上非阻塞方式打开--
O_NONBLOCK 非阻塞方式打开
O_RDONLY|O_NONBLOCK
O_WRONLY|O_NONBLOCK
返回值:
成功,返回文件描述符;
失败,返回-1,更新errno;
例程:
int fd = open("./myfifo", O_WRONLY);
if(fd < 0)
{
perror("open");
return -1;
}
printf("写端打开成功\n");
int fd1 = open("./myfifo1", O_RDONLY);
if(fd1<0)
{
perror("open");
return -1;
}
printf("读端打开成功\n");
往有名管道 write 写数据
char buf[N] = "";
int res = write(fd, buf, strlen(buf));
if(res < 0)
{
perror("write");
return -1;
}
从有名管道 read 读数据
char buf[N] = "";
int res = read(fd1, buf, N);
if(res < 0)
{
perror("read");
return -1;
}
else if(0 == res)
{
printf("对方关闭连接\n");
break;
}
关闭管道
close(fd);
应用例程1
使用有名管道实现AB进程对话
- A进程发送一句话,B进程接收打印;
- B进程发送一句话,A进程接收打印。
- 重复1)2)两步骤
- 当A进程或B进程收到quit QUIT Quit,结束AB进程。
A进程
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#define N 128
int main(int argc, const char *argv[])
{
if(mkfifo("./myfifo", 0664) < 0)
{
if(errno != EEXIST)
{
perror("mkfifo");
return -1;
}
}
printf("创建成功\n");
if(mkfifo("./myfifo1", 0664) < 0)
{
if(errno != EEXIST)
{
perror("mkfifo");
return -1;
}
}
printf("创建成功\n");
int fd = open("./myfifo", O_WRONLY);
if(fd < 0)
{
perror("open");
return -1;
}
printf("写端打开成功\n");
int fd1 = open("./myfifo1", O_RDONLY);
if(fd1<0)
{
perror("open");
return -1;
}
printf("读端打开成功\n");
char buf[N] = "";
while(1)
{
bzero(buf, N);
fprintf(stdout, "请输入>>>");
fgets(buf, N, stdin);
buf[strlen(buf)-1] = 0;
int res = write(fd, buf, N);
if(res < 0)
{
perror("write");
return -1;
}
//从B中读取数据
bzero(buf, N);
res = read(fd1, buf, N);
if(res < 0)
{
perror("read");
return -1;
}
else if(0 == res)
{
printf("对方关闭\n");
break;
}
printf("B说:%s\n", buf);
}
close(fd);
return 0;
}
B进程
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#define N 128
int main(int argc, const char *argv[])
{
if(mkfifo("./myfifo", 0664) < 0)
{
if(errno != EEXIST)
{
perror("mkfifo");
return -1;
}
}
printf("创建成功\n");
if(mkfifo("./myfifo1", 0664) < 0)
{
if(errno != EEXIST)
{
perror("mkfifo");
return -1;
}
}
printf("创建成功\n");
int fd = open("./myfifo", O_RDONLY);
if(fd < 0)
{
perror("open");
return -1;
}
printf("读端打开成功\n");
int fd1 = open("./myfifo1", O_WRONLY);
if(fd1 < 0)
{
perror("open");
return -1;
}
printf("写端打开成功\n");
char buf[N] = "";
while(1)
{
bzero(buf, N);
int res = read(fd, buf, N);
if(res < 0)
{
perror("read");
return -1;
}
else if(0 == res)
{
printf("对方关闭\n");
break;
}
printf("A说:%s\n", buf);
//往A发送数据
bzero(buf, N);
fprintf(stdout, "请输入>>>");
fgets(buf, N, stdin);
buf[strlen(buf)-1] = 0;
res = write(fd1, buf, N);
if(res < 0)
{
perror("write");
return -1;
}
}
close(fd);
return 0;
}
应用例程2
在应用例程1的基础上,实现AB进程可以随时发送,随时接收
A进程
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#define N 128
void* aTob(void*arg)
{
int fd = *(int*)arg;
char buf[N];
while(1)
{
bzero(buf, N);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = 0;
if(write(fd, buf, N)<0)
{
perror("write");
pthread_exit(NULL);
}
}
pthread_exit(NULL);
}
//读取B的信息
void* bToa(void*arg)
{
int fd = *(int*)arg;
char buf[N];
while(1)
{
bzero(buf, N);
int res = read(fd, buf, N);
if(res < 0)
{
perror("read");
pthread_exit(NULL);
}
else if(0 == res)
{
printf("对方关闭\n");
exit(1);
}
printf("B说:%s\n", buf);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建两个有名管道
//myfifo: A-->B
if(mkfifo("./myfifo", 0664))
{
if(errno != EEXIST)
{
perror("errno");
return -1;
}
}
//myfifo1 B-->A
if(mkfifo("./myfifo1", 0664))
{
if(errno != EEXIST)
{
perror("errno");
return -1;
}
}
//打开有名管道
int fd_w = open("./myfifo", O_WRONLY);
if(fd_w<0)
{
perror("open");
return -1;
}
int fd_r = open("./myfifo1", O_RDONLY);
if(fd_r < 0)
{
perror("open");
return -1;
}
//创建两个线程 一个读线程,一个写线程
pthread_t tid_w, tid_r;
if(pthread_create(&tid_w, NULL, aTob, (void*)&fd_w)!=0)
{
perror("pthread_create");
return -1;
}
if(pthread_create(&tid_r, NULL, bToa, (void*)&fd_r)!=0)
{
perror("pthread_create");
return -1;
}
pthread_join(tid_w, NULL);
pthread_join(tid_r, NULL);
close(fd_w);
close(fd_r);
return 0;
}
B进程
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#define N 128
void* bToa(void*arg)
{
int fd = *(int*)arg;
char buf[N];
while(1)
{
bzero(buf, N);
fgets(buf, N, stdin);
buf[strlen(buf)-1] = 0;
if(write(fd, buf, N)<0)
{
perror("write");
pthread_exit(NULL);
}
}
pthread_exit(NULL);
}
//读取A的信息
void* aTob(void*arg)
{
int fd = *(int*)arg;
char buf[N];
while(1)
{
bzero(buf, N);
int res = read(fd, buf, N);
if(res < 0)
{
perror("read");
pthread_exit(NULL);
}
else if(0 == res)
{
printf("对方关闭\n");
exit(1);
}
printf("A说:%s\n", buf);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建两个有名管道
//myfifo: A-->B
if(mkfifo("./myfifo", 0664))
{
if(errno != EEXIST)
{
perror("errno");
return -1;
}
}
//myfifo1 B-->A
if(mkfifo("./myfifo1", 0664))
{
if(errno != EEXIST)
{
perror("errno");
return -1;
}
}
//打开有名管道
int fd_r = open("./myfifo", O_RDONLY);
if(fd_r < 0)
{
perror("open");
return -1;
}
int fd_w = open("./myfifo1", O_WRONLY);
if(fd_w<0)
{
perror("open");
return -1;
}
//创建两个线程 一个读线程,一个写线程
pthread_t tid_w, tid_r;
if(pthread_create(&tid_w, NULL, bToa, (void*)&fd_w)!=0)
{
perror("pthread_create");
return -1;
}
if(pthread_create(&tid_r, NULL, aTob, (void*)&fd_r)!=0)
{
perror("pthread_create");
return -1;
}
pthread_join(tid_w, NULL);
pthread_join(tid_r, NULL);
close(fd_w);
close(fd_r);
return 0;
}
结果
本文链接:https://shengto.top/c/fifo_routine.html
转载时须注明出处及本声明