Inter-process Communication Based on Linux Programming II: Famous Pipeline

A brief description of famous pipelines

Anonymous pipelines can only communicate between processes with affinity, which greatly limits the use of pipelines. The emergence of well-known pipelines breaks through this limitation, enabling communication between any two processes. The pipeline can be indicated by the path name and is visible in the file system. After establishing the pipeline, the two processes can read and write it as ordinary files, which is very convenient to use. However, it is noteworthy that FIFO strictly follows the FIFO first-in-first-out rule. Reading pipelines and FIFOs always returns data from the beginning, while writing them adds data to the end. They do not support file location operations such as lseek().

A named pipe can be created using the function mkfifo(), which is similar to the open() operation in a file and can specify the path and mode of the pipe. Once the pipeline has been created successfully, you can use open(), read(), and write(). As with the development settings of ordinary files, O_RDONLY can be set in open() for pipelines opened for reading and O_WRONLY can be set in open() for pipelines opened for writing. Here, unlike ordinary files, the blocking problem is different. Since there is no blocking problem in the reading and writing of ordinary files, and there is a possibility of blocking in the reading and writing of pipelines, the non-blocking flag here can be set to O_NONBLOCK in the open() function. Read and write of blocked and non-blocked opens are discussed below.

(1) For the reading process

  • If the pipeline is blocked open and there is no data in the FIFO at present, it will be blocked until data is written to the read process.
  • If the pipeline is open non-blocking, the read process will immediately perform the read operation regardless of whether there is data in the FIFO. That is, if there is no data in FIFO, the read function will immediately return 0.
(2) For writing processes

  • If the pipe is blocked open, the write operation will block until the data can be written.
  • If the pipeline is open non-blocking and cannot write all data, the read operation fails to write part or call.

2. Creation Function of Famous Pipeline

The pipe creation function is as follows:

int mkfifo(const char *filename,mode_t mode)
filename: Pipeline to be created

mode: O_RDONLY, Read Pipeline

O_WRONLY, Write Pipeline
O_RDWR, read-write pipeline

O_NONBLOCK: Non-blocking

O_CREAT: If the file does not exist, create a new file and set permissions for it with a third parameter

O_EXCL: If a file exists when using O_CREAT, an error message can be returned. This parameter can be used to test whether a file exists or not.

Return value: 0 successful, other return error code

The following errors often occur in operations as shown in the table below (for error-prone queries):



III. Testing

Write an example for testing: two separate processes need to be written, one process is used to read incoming data and the other process is used to write data; FIFO files created first in the reading process are opened and continuously read the contents of FIFO files, FIFO files are opened in the writing process and then FIFO files are sent to the FIFO files. Write the corresponding content. Specifically as follows:

Reader:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#define FIFO_NAME "yl_fifo"// Define the name of the FIFO file
#define BUFFER_SIZE 256 // Define the size of the buffer

/*	Create FIFO files and read the contents of FIFO files in a blocking manner
 *
 */
int main(void)
{
	int ret;

	int fd;
	char buf[BUFFER_SIZE];
	int buflen;

	/* Create FIFO files */
	if(-1 == access(FIFO_NAME, F_OK))	// Determine whether FIFO files exist
	{
		ret = mkfifo(FIFO_NAME, 0666);  // Create a FIFO file in a readable and writable manner
		if(-1 == ret)
		{
			printf("mkfifo error!\n");
			return -1;
		}
	}

	fd = open(FIFO_NAME, O_RDONLY);		// Open this file
	if(-1 == fd)
	{
		printf("open error!\n");
		return -1;
	}

	/* Read the contents of a file in a blocking manner */
	while(1)
	{
		memset(buf, 0, BUFFER_SIZE);
		buflen = read(fd, buf, BUFFER_SIZE);
		if(buflen > 0)
		{
			buf[buflen] = '\0';
			if(!strcmp("quit", buf))	// If the information read is quit, exit
			{
				return 0;
			}
			else	// Print out the read information
			{
				printf("Read from fifo : %s\n", buf);
			}	
		}
	}
	
	close(fd);	// Close this file
	
	return 0;
}

Writing end:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

#define FIFO_NAME "yl_fifo"// Define the name of the FIFO file
#define BUFFER_SIZE 256 // Define the size of the buffer

/*	Write information to FIFO files
 *		usage : fifo_write <info>
 */
int main(int argc, char *argv[])
{
	int fd;

	char buf[BUFFER_SIZE];
	int buflen;

	if(2 != argc)
	{
		printf("usage : %s <info>\n", argv[0]);
		return -1;
	}

	fd = open(FIFO_NAME, O_WRONLY);		// Open this file
	if(-1 == fd)
	{
		printf("open error!\n");
		return -1;
	}

	/* Write messages into FIFO files */
	sprintf(buf, "%s", argv[1]);
	buflen = write(fd, buf, BUFFER_SIZE);
	if(buflen <= 0)
	{
		printf("write error!\n");
		return -1;
	}
	else
	{
		printf("Write to fifo : %s\n", buf);
	}

	close(fd);		// Close this file

	return 0;
}
Compile and run the reader and the writer as follows:



Added by davey10101 on Tue, 02 Jul 2019 00:47:04 +0300