“This is the 14th day of my participation in the First Challenge 2022.

1. Interprocess communication

This article introduces the communication between processes in Linux. The common ways are as follows:

1.Socket - Network communication2.Pipes -- unnamed pipes -- named pipes -- file --FIFO3.The message queue4.The Shared memory5.Semaphore set6.Signal - Capture signals - The kill command sends signalsint kill(pid_t pid, int sig);
Copy the code

2. Standard flow pipeline

Standard stream pipes support file stream mode just as file operations have standard IO streams. Use to create pipes popen and pclose to connect to another process. Function prototype:

#include <stdio.h>
FILE* popen(const char* command, const char* open_mode);
int pclose(FILE* fp);
Copy the code

Popen is used to start a process, similar to fopen. The second parameter is permission. “r” and “w” are supported.

Pclose Is used to close processes and release resources.

Popen allows you to communicate directly with other started processes.

Example code: Print the contents of /etc/profile from a standard pipe flow:

#include <stdio.h>
#include <stdlib.h>
int main(a)
{
    FILE *file=NULL;
    size_t len=0;
    char buff[1024+1];
    
    file=popen("cat /etc/profile"."r"); // Run cat /etc/profile to set the read mode.
  
  if(file! =NULL)
  {
       len=fread(buff,1.1024,file); / / read the data
       buff[len]='\ 0';
       printf("len=%d\n %s\n",len,buff);
  } 
  pclose(file); // Wait for the thread to end.
  return 0;
}
Copy the code

3. Anonymous pipes

Nameless pipes are used for inter-process communication with related relationships. For example, sibling process, parent-child process, etc.

#include <unistd.h> 
int pipe(int fds[2]);
Copy the code

The pipe function is used to create an unnamed pipe. If successful, FDS [0] stores the readable file descriptor and FDS [1] stores the writable file descriptor.

Returned values: 0 indicates success, -1 indicates failure.

Features of unnamed pipes:

  1. Can only communicate between kin processes (father/child or brother)
  2. Half duplex (fixed read and fixed write)
  3. A virtual pipe file is a special file that exists in memory and can be manipulated using read and write functions.

A pipe, like a water pipe, has two ends, with water coming in at one end and water coming out at the other. The pipe also has two ports, namely the read end and the write end. When the water enters the pipe, the data can be regarded as being written from the write end, and when the water comes out, the data can be seen as being read from the read end. This corresponds to the read and write functions in the program.

Sample code:

#include <stdio.h>
#include <unistd.h>
#include <string.h>int main(int argc,char **argv)
{
    int fds[2];
    FDS [0] corresponds to the read end and FDS [1] corresponds to the write end */
    pipe(fds);
    /*2. Create a child process */
    pid_t pid;
    pid=fork();
    if(pid==0) / / the child process
    {
        char buff[100+1];
        int cnt;
        // Read data from the read end of the pipe
        cnt=read(fds[0],buff,100); // Block
        buff[cnt]='\ 0';
        printf("Data received by child process :%d,%s\n",cnt,buff);
    }
    else / / the parent process
    {
        char buff[]="1234567890";
        // Write data to the write end of the pipe
        write(fds[1],buff,strlen(buff));
        // Wait for the child process to finish
        wait(NULL);
        printf("Parent process terminated normally.\n");
    }
    return 0;
}
Copy the code

4. Name the pipe

Anonymous pipe can only be related interprocess communication greatly limits the use of pipeline, named pipe, a breakthrough the limit by specifying the path name not achieve relevant process in the form of communication between, because using a named pipe communication pipeline is a physical file, exist on disk, and anonymous pipe is the virtual file in memory, other processes cannot be accessed, Unassociated processes cannot communicate with each other.

4.1 How do I Create a Pipe File on the CLI?

Fifo [wbyq@wbyq test]$ls test. Fifo [wbyq@wbyq test]$ls -l0
prw-rw-r--. 1 wbyq wbyq 0 10month15 15:29 test.fifo
Copy the code

4.2 Demonstrate on the command line that two related processes communicate by pipelining files

4.3 Functions to create FIFO files

1.Create a FIFO file#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode); Parameter: pathname: full pathname of the FIFO file to be created. Mode: file access permission, for example0666. Return value: Returns if the creation is successful0, otherwise,- 1.2.Delete the FIFO file#include <unistd.h>
int unlink(const char *pathname);
​
3.Create and delete FIFO files with the command mkfifo. Run the unlink command to delete it.Copy the code

4.4 Creating a Write End: FIFO

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc,char **argv)
{
    if(argc! =2)
    {
        printf("./a.out < FIFO file -- write >\n");
        return 0;
    }
    int fd=open(argv[1],O_WRONLY);
    if(fd<0)
    {
        printf("%s file failed to open.\n",argv[1]);
        return 0;
    }
    char buff[]="1234567890";
    write(fd,buff,strlen(buff));
    close(fd);
    return 0; } Process B is responsible for reading the data#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc,char **argv)
{
    if(argc! =2)
    {
        printf("./a.out < FIFO file -- read >\n");
        return 0;
    }
    int fd=open(argv[1],O_RDONLY);
    if(fd<0)
    {
        printf("%s file failed to open.\n",argv[1]);
        return 0;
    }
    char buff[100+1];
    int cnt;
    cnt=read(fd,buff,100);
    buff[cnt]='\ 0';
    printf("buff=%s\n",buff);
    close(fd);
    return 0;
}
Copy the code

4.5 Creating a Read-end: FIFO

Demonstrate at the command line that two related processes communicate by pipelining files.

Code to create a reader, read data:

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

int main(void)
{
    int fd=0;
    int len=0;
    char buff[100];
	fd=open("myfifo",O_RDONLY);
	len=read(fd,buff,100);
	buff[len]='\ 0';
	printf("read: %s\n",buff);
	return 0;
}
Copy the code