进程间通信之数据传输--FIFO
One of the fundamental features that makes Linux and other Unices useful is the “pipe”. Pipes allow separate processes to communicate without having been designed explicitly to work together. This allows tools quite narrow in their function to be combined in complex ways.
A simple example of using a pipe is the command:
ls | grep x
When bash examines the command line, it finds the vertical bar character | that separates the two commands. Bash and other shells run both commands, connecting the output of the first to the input of the second. The ls program produces a list of files in the current directory, while the grep program reads the output of ls and prints only those lines containing the letter x.
The above, familiar to most Unix users, is an example of an “unnamed pipe”. The pipe exists only inside the kernel and cannot be accessed by processes that created it, in this case, the bash shell. For those who don't already know, a parent process is the first process started by a program that in turn creates separate child processes that execute the program.
The other sort of pipe is a “named” pipe, which is sometimes called a FIFO. FIFO stands for “First In, First Out” and refers to the property that the order of bytes going in is the same coming out. The “name” of a named pipe is actually a file name within the file system. Pipes are shown by ls as any other file with a couple of differences:
% ls -l fifo1
prw-r--r-- 1 andy users 0 Jan 22 23:11 fifo1|
The p in the leftmost column indicates that fifo1 is a pipe. The rest of the permission bits control who can read or write to the pipe just like a regular file. On systems with a modern ls, the | character at the end of the file name is another clue, and on Linux systems with the color option enabled, fifo| is printed in red by default.
On older Linux systems, named pipes are created by the mknod program, usually located in the /etc directory. On more modern systems, mkfifo is a standard utility. The mkfifo program takes one or more file names as arguments for this task and creates pipes with those names. For example, to create a named pipe with the name pipe1 give the command:
mkfifo pipe
The simplest way to show how named pipes work is with an example. Suppose we've created pipe as shown above. In one virtual console1, type:
ls -l > pipe1
and in another type:
cat < pipe
Voila! The output of the command run on the first console shows up on the second console. Note that the order in which you run the commands doesn't matter.
If you haven't used virtual consoles before, see the article “Keyboards, Consoles and VT Cruising” by John M. Fisk in the November 1996 Linux Journal.
If you watch closely, you'll notice that the first command you run appears to hang. This happens because the other end of the pipe is not yet connected, and so the kernel suspends the first process until the second process opens the pipe. In Unix jargon, the process is said to be “blocked”, since it is waiting for something to happen.
One very useful application of named pipes is to allow totally unrelated programs to communicate with each other. For example, a program that services requests of some sort (print files, access a database) could open the pipe for reading. Then, another process could make a request by opening the pipe and writing a command. That is, the “server” can perform a task on behalf of the “client”. Blocking can also happen if the client isn't writing, or the server isn't reading.
Create two named pipes, pipe1 and pipe2. Run the commands:
echo -n x | cat - pipe1 > pipe2 &
cat <pipe2 > pipe1
On screen, it will not appear that anything is happening, but if you run top (a command similar to ps for showing process status), you'll see that both cat programs are running like crazy copying the letter x back and forth in an endless loop.
After you press ctrl-C to get out of the loop, you may receive the message “broken pipe”. This error occurs when a process writing to a pipe when the process reading the pipe closes its end. Since the reader is gone, the data has no place to go. Normally, the writer will finish writing its data and close the pipe. At this point, the reader sees the EOF (end of file) and executes the request.
Whether or not the “broken pipe” message is issued depends on events at the exact instant the ctrl-C is pressed. If the second cat has just read the x, pressing ctrl-C stops the second cat, pipe1 is closed and the first cat stops quietly, i.e., without a message. On the other hand, if the second cat is waiting for the first to write the x, ctrl-C causes pipe2 to close before the first cat can write to it, and the error message is issued. This sort of random behavior is known as a “race condition”.
Bash uses named pipes in a really neat way. Recall that when you enclose a command in parenthesis, the command is actually run in a “subshell”; that is, the shell clones itself and the clone interprets the command(s) within the parenthesis. Since the outer shell is running only a single “command”, the output of a complete set of commands can be redirected as a unit. For example, the command:
(ls -l; ls -l) >ls.out
writes two copies of the current directory listing to the file ls.out.
Command substitution occurs when you put a < or > in front of the left parenthesis. For instance, typing the command:
cat <(ls -l)
results in the command ls -l executing in a subshell as usual, but redirects the output to a temporary named pipe, which bash creates, names and later deletes. Therefore, cat has a valid file name to read from, and we see the output of ls -l, taking one more step than usual to do so. Similarly, giving >(commands) results in Bash naming a temporary pipe, which the commands inside the parenthesis read for input.
If you want to see whether two directories contain the same file names, run the single command:
cmp <(ls /dir1) <(ls /dir2)
The compare program cmp will see the names of two files which it will read and compare.
Command substitution also makes the tee command (used to view and save the output of a command) much more useful in that you can cause a single stream of input to be read by multiple readers without resorting to temporary files—bash does all the work for you. The command:
ls | tee >(grep foo | wc >foo.count) \
>(grep bar | wc >bar.count) \
| grep baz | wc >baz.count
counts the number of occurrences of foo, bar and baz in the output of ls and writes this information to three separate files. Command substitutions can even be nested:
cat <(cat <(cat <(ls -l))))
works as a very roundabout way to list the current directory.
As you can see, while the unnamed pipes allow simple commands to be strung together, named pipes, with a little help from bash, allow whole trees of pipes to be created. The possibilities are limited only by your imagination.
摘抄自: https://www.linuxjournal.com/article/2156
Named Pipe or FIFO with example C program
In computing, a named pipe (also known as a FIFO) is one of the methods for intern-process communication.
- It is an extension to the traditional pipe concept on Unix. A traditional pipe is “unnamed” and lasts only as long as the process.
- A named pipe, however, can last as long as the system is up, beyond the life of the process. It can be deleted if no longer used.
- Usually a named pipe appears as a file, and generally processes attach to it for inter-process communication. A FIFO file is a special kind of file on the local storage which allows two or more processes to communicate with each other by reading/writing to/from this file.
- A FIFO special file is entered into the filesystem by calling mkfifo() in C. Once we have created a FIFO special file in this way, any process can open it for reading or writing, in the same way as an ordinary file. However, it has to be open at both ends simultaneously before you can proceed to do any input or output operations on it.
Creating a FIFO file
In order to create a FIFO file, a function calls i.e. mkfifo is used.
int mkfifo(const char *pathname, mode_t mode);
Using FIFO
As named pipe(FIFO) is a kind of file, we can use all the system calls associated with it i.e. open, read, write, close.
Example Programs to illustrate the named pipe.
There are two programs that use same FIFO. The program 1 writes first, then reads. The program 2 reads first, then writes. They both keep doing it until terminated.
Program 1(Writes first)
// C program to implement one side of FIFO
// This side writes first, then reads
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> int main()
{
int fd; // FIFO file path
char * myfifo = "/tmp/myfifo"; // Creating the named file(FIFO)
// mkfifo(<pathname>, <permission>)
mkfifo(myfifo, ); char arr1[], arr2[];
while ()
{
// Open FIFO for write only
fd = open(myfifo, O_WRONLY); // Take an input arr2ing from user.
// 80 is maximum length
fgets(arr2, , stdin); // Write the input arr2ing on FIFO
// and close it
write(fd, arr2, strlen(arr2)+);
close(fd); // Open FIFO for Read only
fd = open(myfifo, O_RDONLY); // Read from FIFO
read(fd, arr1, sizeof(arr1)); // Print the read message
printf("User2: %s\n", arr1);
close(fd);
}
return ;
}
Program 2(Reads First)
// C program to implement one side of FIFO
// This side reads first, then reads
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> int main()
{
int fd1; // FIFO file path
char * myfifo = "/tmp/myfifo"; // Creating the named file(FIFO)
// mkfifo(<pathname>,<permission>)
mkfifo(myfifo, ); char str1[], str2[];
while ()
{
// First open in read only and read
fd1 = open(myfifo,O_RDONLY);
read(fd1, str1, ); // Print the read string and close
printf("User1: %s\n", str1);
close(fd1); // Now open in write mode and write
// string taken from user.
fd1 = open(myfifo,O_WRONLY);
fgets(str2, , stdin);
write(fd1, str2, strlen(str2)+);
close(fd1);
}
return ;
}
Output: Run the two programs simultaneously on two terminals.
摘抄自:https://www.geeksforgeeks.org/named-pipe-fifo-example-c-program/
进程间通信之数据传输--FIFO的更多相关文章
- 进程间通信之数据传输--Socket
The client server model Most interprocess communication uses the client server model. These terms re ...
- 进程间通信和同步:pipe、FIFO、消息队列、信号量、共享内存、信号
一.半双工管道(pipe) 关于管道详细介绍可参考http://www.cnblogs.com/nufangrensheng/p/3560130.html. 1.管道实现父子进程间通信实例: /* p ...
- 查漏补缺:进程间通信(IPC):FIFO
1.FIFO FIFO,又称命名管道.不同于pipe管道的只能用于拥有共同祖先进程的两个进程间通信,因FIFO通过路径绑定,所以即使是不相关的进程间也可通过FIFO进行数据交换. FIFO是一种文件类 ...
- IPC 进程间通信方式——管道
进程间通信概述 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到. 通知时间: ...
- Linux学习笔记25——命名管道(FIFO)
1 命名管道(FIFO) 管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信.后来从管道为基础提出命名管道(named pipe,FIFO)的概念,该限制得到了克服.FIFO不同于管道 ...
- Python::OS 模块 -- 文件和目录操作
os模块的简介参看 Python::OS 模块 -- 简介 os模块的进程管理 Python::OS 模块 -- 进程管理 os模块的进程参数 Python::OS 模块 -- 进程参数 os模块中包 ...
- 开创学习的四核时代-迅为iTOP4412学习开发板
产品特点: 处理器: Exynos 4412 处理器,Cortex-A9四核,功耗性能俱佳! 性能: 1GB(可选2GB) 双通道 64bit数据总线 DDR3: 4GB(可选16GB)固态硬盘EMM ...
- linux服务器开发二(系统编程)--进程相关
进程相关的概念 程序与进程 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(CPU.内存.打开的文件.设备.锁等等). 进程,是一个抽象的概念,与操作系统原理联系紧密.进程是活跃的程序,占用系 ...
- python OS 模块 文件目录操作
Python OS 模块 文件目录操作 os模块中包含了一系列文件操作的函数,这里介绍的是一些在Linux平台上应用的文件操作函数.由于Linux是C写的,低层的libc库和系统调用的接口都是C AP ...
随机推荐
- pytorch中使用cuda扩展
以下面这个例子作为教程,实现功能是element-wise add: (pytorch中想调用cuda模块,还是用另外使用C编写接口脚本) 第一步:cuda编程的源文件和头文件 // mathutil ...
- EasyNVR摄像机网页无插件直播方案H5前端构建之:如何区分PC端和移动端
背景分析 随着互联网基础设施建设的不断完善和发展,带宽的不断提速,尤其是光纤入户,4G/5G/NB-IoT各种网络技术的大规模商用,视频随时随地可看.可控的诉求越来越多,尤其是移动应用技术和前端技术的 ...
- coding git push 403 时
直接修改 项目目录下的 .git/config url url = https://coding用户名:coding密码@git.coding.net/coding账号/coding项目名称.gi ...
- jstree: 获得根节点,checkbox事件处理
$.jstree.defaults.core.themes.responsive = true; $.jstree.defaults.checkbox.three_state = false;// 如 ...
- go 调度机制简介
goroutine是go中最重要的功能之一,正是因为有了goroutine这样强大的工具,go在并发方面表现的特别优秀. 那么goroutine和普通的线程和协程有什么区别呢?首先,我们需要明白线程和 ...
- RTSP Spectification
Refer: https://www.ietf.org/rfc/rfc2326.txt Network Working Group H. SchulzrinneRequest for Comments ...
- Git config文件
查看该文件: git config --global --list Ref: https://blog.csdn.net/themagickeyjianan/article/details/79683 ...
- [转帖]从0开始的高并发(一)--- Zookeeper的基础概念
从0开始的高并发(一)--- Zookeeper的基础概念 https://juejin.im/post/5d0bd358e51d45105e0212db 前言 前面几篇以spring作为主题也是有些 ...
- Vue框架(二)——Vue指令(v-once指令、v-cloak指令、条件指令、v-pre指令、循环指令)、todolist案例、Vue实例(计算、监听)、组件、组件数据交互
Vue指令 1.v-once指令 单独使用,限制的标签内容一旦赋值,便不可被动更改(如果是输入框,可以主动修改) <!DOCTYPE html> <html lang=" ...
- DRF框架(三)——media资源路径设置、多表设计复习及补充、序列化组件(ModelSerializer)操作多表(序列化与反序列化)、多表序列化与反序列化整合(重点)
media资源路径设置 (设置好后把图片放在这个文件夹中,通过链接能访问到图片) 1.先在根目录设置一个media文件夹 2.配置settings.py,加上下面的 MEDIA_URL = '/me ...