Linux system programming pipeline (III): named pipeline FIFO and mkfifo Functions

Source: Internet
Author: User
Tags unix domain socket

Inter-process communication must pass through the channel provided by the kernel, and there must be a way to identify a channel provided by the kernel in the process. The previously mentioned anonymous channel is identified by the opened file descriptor. If the processes that want to communicate with each other do not inherit the file descriptor from the common ancestor, how do they communicate? The kernel provides a channel. The question is, how can we identify this channel so that all processes can access it? The path name in the file system is global and accessible to all processes. Therefore, you can use the path name in the file system to identify an IPC channel.


Both the FIFO and Unix domain socket IPC Mechanisms are identified by special files in the file system.

A fifo file has no data blocks on the disk and is used to identify only one channel in the kernel, for example, prw-RW-r -- 1 Simba 0 May 21 P2, the file type is P, indicating FIFO, and the file size is 0. Each process can open this file for read/write, which is actually a kernel channel for reading and writing (the root cause is that the Read and Write Functions pointed to by this file struct are different from those of conventional files ), in this way, inter-process communication is realized. UNIX
The principle of domain socket and FIFO is similar. A special socket file is also required to identify the channel in the kernel. For example, the/run directory contains many System Service socket files:

SRW-RW-1 Root 0 May 21 09:59 acpid. Socket

....................

File type s indicates socket. These files do not have data blocks on the disk.


1. Named Pipe (FIFO)

One restriction of anonymous pipeline applications is that they can only communicate with each other in a process with a common ancestor (kinship.
If we want to exchange data between unrelated processes, we can use a FIFO file to do this, which is often called a named pipe.

You can create a named pipe from the command line by using the following command:
$ Mkfifo filename
The named pipeline can also be created from the program. Related functions include:
Int mkfifo (const char * filename, mode_t mode );


Ii. Named and anonymous Pipelines

The anonymous pipeline is created and opened by the pipe function.
The named pipe is created by the mkfifo function and open with open.
The only difference between FIFO (named pipeline) and pipe (anonymous pipeline) is that they are created and opened in different ways and have the same semantics after these tasks are completed.

The only difference between pipes and operating OS is the manner in which they are created and opened. Once these tasks have been accomplished, I/O on pipes and Guest OS has exactly the same semantics.


Iii. Rules for opening Named Pipes

If the read-only FIFO is enabled for the current open operation
O_nonblock Disable: it is blocked until a corresponding process opens the FIFO for writing.
O_nonblock enable: returns success immediately
If the current open operation is for writing and the FIFO is enabled
O_nonblock Disable: it is blocked until a corresponding process opens the FIFO for reading.
O_nonblock enable: an error is returned immediately and the error code is enxio.


It should be noted that the opened file descriptor is blocked by default. You can write two very simple applets to test it. This is mainly a statement.

Int FD = open ("p2", o_wronly );
Assume that P2 is a named pipeline file. Replace the open flag with o_rdonly as another program. You can run the RD program first, which will block the program and then run the WR program in another window, both programs return success from open. It is not difficult to test it when it is not blocked. You can add a flag when it is open.

Note that the read and write rules of the command pipeline and anonymous pipeline are the same. For details, refer to here.


The following example shows how to name an MPS queue to copy objects:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*************************************** **********************************
> File name: Process _. c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <signal. h>
# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Int main (INT argc, char * argv [])
{
Mkfifo ("TP", 0644 );
Int infd = open ("makefile", o_rdonly );
If (infd =-1)
Err_exit ("Open error ");

Int outfd;
Outfd = open ("TP", o_wronly );
If (outfd =-1)
Err_exit ("Open error ");

Char Buf [1024];
Int N;
While (n = read (infd, Buf, 1024)> 0)
Write (outfd, Buf, N );

Close (infd );
Close (outfd );

Return 0;
}


The program uses the mkfifo function to create a named pipeline file Tp and read all makefile files to the TP file.


C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*************************************** **********************************
> File name: Process _. c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <signal. h>
# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Int main (INT argc, char * argv [])
{

Int outfd = open ("makefile2", o_wronly | o_creat | o_trunc, 0644 );
If (outfd =-1)
Err_exit ("Open error ");

Int infd;
Infd = open ("TP", o_rdonly );
If (infd =-1)
Err_exit ("Open error ");

Char Buf [1024];
Int N;
While (n = read (infd, Buf, 1024)> 0)
Write (outfd, Buf, N );

Close (infd );
Close (outfd );
Unlink ("TP"); // delete a name and possibly the file it refers
Return 0;
}

We can see that the program is the opposite, that is, reading from TP to makefile2 to complete the file copy function. Here An unlink function is used, which belongs to the inode_operations series, that is, inode reference count minus 1. When the reference count is 0 and the process has disabled the file descriptor, the file will be deleted.


Reference: apue

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.