- 专栏内容:linux下并发编程
- 个人主页:我的主页
- 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.
目录
前言
概述
原理介绍
接口说明
代码演示
结尾
前言
本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。
概述
在不同进程和程序间如何传递少量数据,且能阻塞形式使用,这就用到了管道。管道分为两种,无名管道和命名管道,因为子进程可以复制父进程的进程上下文,所以无名管道用在父子进程间,而命名管道在不同进程间通过路径名进行共享,更加通用。
原理介绍
命名管道是一种在进程间进行通信的机制,它可以用于在两个进程间进行数据传输。具体来说,命名管道是一种特殊类型的文件,它可以在不同的进程中被打开和读写,从而实现了进程间的通信。一般情况下,在Linux系统中,命名管道的创建和使用是通过C语言的相关API实现的。
建立管道文件后,可以在路径下看到,它的文件类型为 p ,说明它是管道文件。管道文件不同于一般文件的是,写时会阻塞,至到数据被读出,而在读时无数据的话会阻塞等待,直到有数据被写入。
通过系统命令也可以创建命名管道,如下:
[senllang@localhost pipetest]$ mkfifo /tmp/myfilo
[senllang@localhost pipetest]$ ll /tmp/
total 0
prw-r--r--. 1 senllang develops 0 Apr 8 15:52 myfilo
可以看到管道文件的类型为 p,我们打开两个终端进行读写测试。
终端一写入
[senllang@localhost pipetest]$ echo "hello" > /tmp/myfifo
因为没有读,此时会卡住
终端二读取
[senllang@localhost ~]$ cat /tmp/myfifo
hello
可以看到读出了hello,此时终端一也会解除阻塞。同样先读取也会阻塞,直到写入数据为至。
接口说明
(1)管道文件创建
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
通过传递路径pathname和mode权限来创建管道文件。
#include <fcntl.h> /* Definition of AT_* constants */
#include <sys/stat.h>
int mkfifoat(int dirfd, const char *pathname, mode_t mode);
这是另一个版本,当pathname是相对路径时,创建路径是在dirfd指定的目录下。当dirfd为 AT_FDCWD时,用mkfifo效果一样。
(2)管道文件打开/读写/关闭
常用的文件操作 open/read/write/close
(3)删除管道文件
unlink(fd)
在用完管道时,需要删除管道文件,和删除文件类似。
代码演示
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
int fd;
char *myfifo = "/tmp/myfifo";
char input[256];
char output[256];
/* create named pipe */
mkfifo(myfifo, 0666);
/* open named pipe for reading */
fd = open(myfifo, O_RDWR);
while(1)
{
/* read input from named pipe */
read(fd, input, 256);
/* convert input to uppercase */
int i;
for (i = 0; input[i]; i++)
{
output[i] = toupper(input[i]);
}
/* write output to named pipe */
int len = i;
write(fd, output, len);
}
/* close named pipe */
close(fd);
unlink(myfifo);
return 0;
}
编译后运行,管道里的字符串被程序转为大写后又写入管道。
[senllang@localhost pipetest]$ gcc mkfifo_ex01.c -o mkfifo_ex01
[senllang@localhost pipetest]$ ./mkfifo_ex01
在另一个终端写入字符串,
[senllang@localhost ~]$ echo "hello" >/tmp/myfifo
[senllang@localhost ~]$ cat /tmp/myfifo
HELLO
结尾
作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。
注:未经同意,不得转载!