Inter-process communication (5)

Source: Internet
Author: User
Tags echo command

Famous pipelines: FIFO

So far, we can only transmit data between two related programs, that is, programs started by a common ancestor process. This is usually not very convenient, because we want unrelated processes to exchange data.

We can use FIFO to implement this operation, which is usually called a famous Pipeline. A famous pipeline is a special file type that exists as a name in the file system (remember, everything in Linux is a file), but the behavior is similar to an unknown pipeline we know.

You can use a command line or a program to create a famous Pipeline. For historical reasons, the command used to create a famous pipeline is mknod:

$ Mknod filename P

However, the mknod command is not in the X/Open command list, so it is not available on all UNIX-like systems. A better command line method is to use

$ Mkfifo filename

In the program, we can use two different commands:

# Include <sys/types. h>
# Include <sys/STAT. h>
Int mkfifo (const char * filename, mode_t mode );
Int mknod (const char * filename, mode_t mode | s_ififo, (dev_t) 0 );

Similar to the mknod command, we can use the mknod function to create many special file types. Using a value of the dev_t type and a s_ififo or file access model is the only portable method for creating a famous Pipeline Function. In our example, we will use the simplified mkfifo.

Test-create a famous Pipeline

As o1.c, you only need to enter the following code:

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <sys/types. h>
# Include <sys/STAT. h>

Int main ()
{
Int res = mkfifo ("/tmp/my_fifo", 0777 );
If (RES = 0)
Printf ("FIFO created/N ");
Exit (exit_success );
}

We can use the following command to view the pipeline:

$ LS-LF/tmp/my_fifo
Prwxr-XR-x 1 Rick users 0 July 10 14:55/tmp/my_fifo |

Note that the first character of the output is P, indicating a pipeline. | Is added to the-F option of the LS command, which also indicates a pipeline.

Working Principle

The program uses the mkfifo function to create a special file. Although we request a 0777 mode, this mode is modified by the user mask settings, just like in normal file creation, so the final file mode is 755. If our umask settings are different, for example, 0002, we will see different permissions.

You can use the RM command or call the unlink system in a program to delete the FIFO as if you were removing a common file.

Access FIFO

One of the most useful features of famous pipelines is that they appear in file systems and can be used like file names. Before using the FIFO file we created for more programming, we can use common file commands to explore the behavior of FIFO files.

Test-access a FIFO file

1 first, let's try to read (empty) FIFO files:

$ Cat </tmp/my_fifo

2. Try to write data to FIFO now. We need to use another terminal because the first terminal is being suspended and waiting for data to appear in the FIFO.

$ Echo "sdsdfasdf">/tmp/my_fifo

We can see the results output by the cat command. If we do not send any data to the FIFO, the cat command will be suspended until we interrupt it, usually using Ctrl + C.

3. We can add the first command to the backend and complete two operations at the same time:

$ Cat </tmp/my_fifo &
[1] 1316
$ Echo "sdsdfasdf">/tmp/my_fifo
Sdsdfasdf
[1] + done cat </tmp/my_fifo
$

Working Principle

Because there is no data in the FIFO, the cat and echo programs will block and wait for the data to arrive and read data from a process respectively.

Take a look at Step 3. The cat process is initially blocked in the background. When the echo Command makes some data available, the cat command reads the data and outputs it to the standard output. Note that the cat command will immediately exit without waiting for more data. It is not blocked because the pipeline will be closed after the second command completely puts the data into the FIFO, so the read call in the CAT program will return 0, indicating the end of the file.

Now we can see how the command line program FIFO acts. Now let's take a closer look at the program interface, this is where the read and write operations allow us to perform more control when we access the FIFO.

Note: Unlike the pipeline created by pipe, FIFO exists as a naming file, rather than an open file descriptor, and must be opened after it can be read and written. We can use the open and close functions when operating on the files before to open and close a FIFO. For an open call, a FIFO path name must be passed, instead of a regular file.

Enable FIFO with open

The main restriction for enabling FIFO is that a program using the o_rdwr model may not open a FIFO program for reading and writing. If a program does this, the result is undefined. This is a reasonable limitation, because we usually use FIFO to transmit data in one direction, so we do not need the o_rdwr model. The process will read its own output.

If we want to implement two-way data transmission between programs, it is best to use a pair of FIFO, or pipelines, each for one direction, or to change the direction of the data stream by closing the display and re-opening the FIFO. We will discuss two-way data exchange later in this chapter.

Opening a FIFO file differs from opening a regular file in that the open tag with the o_nonblock option (the second parameter of open ). Using this open mode not only changes how open calls are processed, but also changes how read and write requests are processed on the returned file descriptor.

There are four valid combinations of o_rdonly, o_wronly, and o_nonblock tags. We will consider each one in sequence.

Open (const char * path, o_rdonly );

In this case, the open call will be blocked; this call will not be returned until a process opens the same FIFO for writing. This is similar to the previous cat Example.

Open (const char * path, o_rdonly | o_nonblock );

The open call will be successful and will be returned immediately, although the FIFO is not opened by any process for writing data.

Open (const char * path, o_wronly );

In this case, the open call is blocked until a process opens the same FIFO for reading.

Open (const char * path, o_wronly | o_nonblock );

This call will return immediately, but if no process opens FIFO for reading, open will return error-1, and FIFO will not be opened. If a process enables FIFO to be opened for reading, the returned file descriptor can be used to write data to FIFO.

Note: The difference between o_nonblock and o_rdonly and o_wronly is that in non-blocking situations, if no process causes the pipeline to open for reading, the open call for writing will fail, however, non-blocking read calls do not fail. The o_nonblock flag does not affect the close call.

Test-open a FIFO file

Next, let's take a look at how to use open with the o_nonblock mark to synchronize two processes. We will not use multiple subprograms. On the contrary, we will write a test program named fifo2.c. This program will discuss FIFO behavior by passing different parameters.

1. We start with the header file and # define, and check the correct number of command line parameters provided:

# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <sys/types. h>
# Include <sys/STAT. h>

# Define o_name "/tmp/my_fifo"

Int main (INT argc, char ** argv)
{
Int res;
Int open_mode = 0;

If (argc <2)
{
Fprintf (stderr, "Usage: % S <some comination of o_rdonly o_wronly o_nonblock>/N", * argv );
Exit (exit_failure );
}

2. If the program passes the correct parameters, we can set the value of open_mode by these parameters:

Argv ++;
If (strncmp (* argv, "o_rdonly", 8) = 0) open_mode | = o_rdonly;
If (strncmp (* argv, "o_wronly", 8) = 0) open_mode | = o_wronly;
If (strncmp (* argv, "o_nonblock", 10) = 0) open_mode | = o_nonblock;

Argv ++;
If (* argv)
{
If (strncmp (* argv, "o_rdonly", 8) = 0) open_mode | = o_rdonly;
If (strncmp (* argv, "o_wronly", 8) = 0) open_mode | = o_wronly;
If (strncmp (* argv, "o_nonblock", 10) = 0) open_mode | = o_nonblock;
}

3. Check whether the FIFO exists. If necessary, create a FIFO instance. Then, the FIFO will be opened and output will be generated. The first FIFO is disabled.

If (access (export o_name, f_ OK) =-1)
{
Res = mkfifo (Bytes o_name, 0777 );
If (res! = 0)
{
Fprintf (stderr, "cocould not create FIFO % s/n", stored o_name );
Exit (exit_failure );
}
}

Printf ("process % d Open FIFO/N", getpid ());
Res = open (kerbero_name, open_mode );
Printf ("process % d result % d/N", getpid (), Res );
Sleep (5 );
If (res! =-1) (void) Close (RES );
Printf ("process % d finished/N", getpid ());
Exit (exit_success );
}

Working Principle

This program allows us to specify the combination of o_rdonly, o_wronly, and o_nonblock on the command line. By comparing known strings with command line parameters, if the strings match, the corresponding tag is set. This program uses the access function to check whether the FIFO exists. If necessary, this file will be created.

We have not destroyed the FIFO because we have no way to identify whether other programs are using FIFO.

O_rdonly and o_wronly with o_nonblock

Now we have a test program. Let's test some combinations. Note that we put the file program in the background:

$./Fifo2 o_rdonly &
[1] 152
Process 152 opening FIFO
$./Fifo2 o_wronly
Process 153 opening FIFO
Process 152 result 3
Process 153 result 3
Process 152 finished
Process 153 finished

This is the most common use of famous pipelines. It starts with the read process and waits in the open call. Then, when the second program opens the FIFO, both programs will continue. Note that the Read and Write processes are synchronized during the open call.

Note: When a Linux Process is blocked, it does not consume CPU resources, so this process synchronization method is very effective.

O_rdonly and o_wronly with o_nonblock

This time, the read process executes the open call and continues immediately, although there is no write process. The write process will continue immediately after the open call, because the FIFO is enabled for reading.

$./Fifo2 o_rdonly o_nonblock &
[1] 160
Process 160 opening FIFO
$./Fifo2 o_wronly
Process 161 opening FIFO
Process 160 result 3
Process 161 result 3
Process 160 finished
Process 161 finished
[1] + done 1_o2 o_rdonly o_nonblock

These two examples are the most common combination of open mode. We can use other combinations to test this program.

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.