[Linux] - inter-process communication

Interprocess communication (IPC)

Prior to this, we have to understand the reason why the operating system to provide inter-process communication to users?

For chestnuts, why we can be very smooth and connect with other people? A: Because air is a medium spread of sound. Well, you can look at the analogy, between independence process, which is operating its own virtual address space, it can not communicate directly with other processes. If there is no public media between two independent entities, they will not communicate, the operating system is to provide such a public medium.

Communication scenario: data transfer, data sharing, data control
communication between processes There are four: pipe, shared memory, message queues, semaphores
1, the pipe
conduit is essentially a kernel buffer, via multiple processes accessing the same piece buffer for communication.
Category pipes: anonymous pipes and named pipes
(1) anonymous pipe
a process system calls in the kernel creates a pipeline, and the call returns a handle to operate the pipeline, this pipeline there is no other identifier, it can only be accessed by the operating handle. Therefore, only anonymous pipes for interprocess communication, that are related, because the only copy of the parent by the child with a way to get a handle to operate the pipeline, and then access the same buffer. And be sure to create a child process created before.
Operation pipeline handles: two file descriptors.
The question is, why have two? In fact, this pipeline with our everyday life a little bit like, into a one out. However, we under Linux a conduit for reading data, one for writing data.

Function: int pipe (int pipefd [2
]) -----> int pipefd [2] pipe (pipefd) means that there is an array of type int two elements, then the first address of the array pass in, through the return pipefd two operating handles. Wherein:
pipefd [0] - is used to read data pipeline
pipefd [1] - for writing data to the pipeline

Return Value: returns 0 on success, -1 failure
Example:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main()
{
        int pid=0;
        int pipefd[2];
        int ret=pipe(pipefd);  //创建管道应该在创建子进程之前
        if(ret<0)
          {
            perror("pipe error\n");
            return -1;
           }
        pid=fork();  //创建进程
        if(pid==0)   //子进程读数据
          {
          char buf[1024]={0};
          int ret=read(pipefd[0],buf,1023);
          if(ret<0)
         {
         perror("read error\n");
         return -1;
          }
        printf("child read data:[%s]\n",buf);
          }
        else  //父进程写数据
      {
         char *ptr="cold day";
        int ret=write(pipefd[1],ptr,strlen(ptr));
        if(ret<0)
        {
        perror("write error\n");
        return -1;
        }
     }
 }

The result:
you can see, the child and the parent process read data write data is consistent.
Here Insert Picture Description
** 1) ** If you let the parent process that sleep (5)? What happens then? In fact, this means that the pipeline would be no data because five seconds before the start, the parent process did not produce data, the child read when it will block until there is data
** 2) ** When the pipeline is full of data, write continue to write data blocks until the data is read out
in the following figure, we let the child sleep 5 seconds

if(pid==0)   //子进程读数据
          {
          sleep(5);
          char buf[1024]={0};
          ........

Let the parent process to write data, and calculates the sum of the length of the data

else  //父进程写数据
     {
     int pipe_size=0;   //定义起始数据长度为0
     while(1)
     {
        char *ptr="cold day";
        int ret=write(pipefd[1],ptr,strlen(ptr));
        if(ret<0)
        {
        perror("write error\n");
        return -1;
        }
     }
     pipe_size+=ret;  //写入的数据长度总和
     printf("write data:%d\n",pipe_size);  //打印总共写了多少
     }

The program runs, the child will sleep first five seconds, then the parent process is writing data, time slice after, the child wakes up, then began to read the data, let's look at the results (no control over the output format is good here, forgive me):
Here Insert Picture Description
results also confirms our conjecture, 65536 parent wrote, when the child begins reading.
** 3) ** If all the write end of the pipe is closed, then read the data after reading do not block the pipeline, but returns 0 (returns 0, indicating no one to write, continue to read the words that have no meaning)
* * 4) ** If all the read end of the pipe is closed, when the write data is written, it will trigger an exception, the process exits
Here Insert Picture Description
as shown we closed the read end of the parent process, then the process will quit unexpectedly.
5 **) ** read when the pipeline, if the write data size is not more than PIPE_BUF = 4096 size, the atomic operation can be guaranteed.
These are the five characteristics we are talking about the pipeline.

Mutually exclusive: Only one can perform operations critical resource data stream to achieve the security of operational data, ensure the safe operation of the data
synchronization: Judgment by timing, to achieve access to the resources of the street timing rationality
(2) name pipeline
named pipes: kernel buffer has a piece identifier that is found in a file system piping
characteristics: any process can be used on the same inter-host communication
Note: If the named pipe to read-only open it will block until the pipeline file by other processes to write the way open
if the named pipe to write only way open will block until the pipeline file by other processes to read the way open
function: int mkfifo (const char * pathname , mode_t mode )
pathname: path name pipeline
mode: operating authority pipeline file
return value: the successful return 0, -1 failure
following demo demonstrates the basic operation of named pipes:

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

int main()
{
  char *file="./test.fifo";
  int ret=mkfifo(file,0664);   //创建一个管道
    if(ret<0)
    {
      if(errno!=EEXIST)   //说明是其他方面的报错
      {
      perror("mkfifo error");
      return -1;
      }
    }
    int fd=open(file,O_RDWR);  //以可读可写方式打开这个文件
    if(fd<0)
    {
    perror("open error");
    return -1;
    }
    printf("open success\n");
    return 0;
}

When we compile the code is compiled successfully found
Here Insert Picture Description

2, shared memory

Shared memory: data sharing between use and process
characteristics: inter-process communication fastest way
to achieve the principles:
1) to open up a space in physical memory, this space is in the kernel has identified
2) this space by the page to map their virtual address space
3) operations carried out by the virtual memory address
4) removes the association between
5) delete the shared memory

  • Compared to other shared memory inter-process communication, in the communication process, data is copied twice less user mode and kernel mode, and therefore is the fastest.

Carve out a memory: int shmget (key_t key, size_t size, int shmflag)

  • Parameter Description:
    Key: identifying the shared memory in the kernel, and other processes open the same memory through the same logo
    size: shared memory size
    shmflg: IPC_CREAT | IPC_EXCL | mode flag
    Return value: the successful return of the operating handle shared memory failure return -1;

Establish the mapping: void the shmat (int shmid, const void shmaddr, int shmflg)

Parameters:
the shmid: Operating handle
by shmaddr: mapping the first address
shmflg: Operation
Return Value: returns the first address mapping success, failure -1

shmdt (shm_start); the mapping relationship, alluding to the first address can be placed

shmctl (shmid, IPC_RMID, NULL); remove shared memory

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>

#define IPC_KEY 0x12345678
#define SHM_SIZE 4096

int main()
{
        int shmid=shmget(IPC_KEY,SHM_SIZE,IPC_CREAT|664);  //创建一个共享内存
        if(shmid<0){
          perror("shmget error");
          return -1;
        }
        void *shm_start=shmat(shmid,NULL,0);   
        if(shm_start==(void*)-1)
        {
          perror("start error");
          return -1;
        }
        int i=0;
        while(1)
        {
          sprintf(shm_start,"%s-%d\n","good day",i++);//格式化字符串放到buff里面
          sleep(1);
        }
        shmdt(shm_start);  //解除映射关系,放入影射首地址就可以
        shmctl(shmid,IPC_RMID,NULL);  //删除共享内存
        return 0;
}

3, the message queue

  • Action: a data block transmission between processes

  • Essence: kernel priority queue, a plurality of processes by placing a queue node to a queue or obtaining the same node communicate

  • The principle
    (1) create a queue in the kernel
    (2) adding a node to the queue
    (3) obtain from the queue node
    (4) delete the message queue

  • Characteristics:
    (1) carrying a message queue synchronization and mutual exclusion: If the queue is no data, the receiver will be blocked, if the queue is full, then the data is also added obstruction
    (2) has a transmission data block type
    (3) data is not adhesions
    message queue has now been eliminated

4, the semaphore

  • Semaphore: synchronization and mutual exclusion between processes for
    mutual exclusion: only one process can access to critical resources at the same time, safe operation of data - data access security
    synchronization: judging by a number of conditions have to achieve critical resources the reasonableness of data access - access order
  • Essence: + is a counter waiting queue, but only 0/1 counter two states
  • achieve
  • Exclusive: the amount of access by the current state of a state marker critical resources; this marks the first judgment before the critical resource access, if the state can be accessed, this status will be modified as inaccessible, and to access data, access will be completed before Revised status to be accessible. Implement a counter by only 0/1
  • Synchronization: via a counter for counting the number of resources, when you want to get critical resources, first determine the count, if resources are accessible, and if so, count-1, to obtain a resource to operate, if no resources (ie is count <= 0), then waits until the other process production data count + 1, and then wake up waiting process. A determination is achieved by counting the wake-up function and wait
  • PV semaphore primitives
  • p operations: determination of the count, then -1 if no resource is waited
  • v Operation: +1 odd, wake-up process is waiting in the queue pending

to sum up

The author of communication between processes on the first consolidation here, inadequate follow-up will continue revised to add, please also concerned about the follow-up signal Linux-

Published 33 original articles · won praise 13 · views 1065

Guess you like

Origin blog.csdn.net/Vicky_Cr/article/details/103101187