2017-2018-1 20155222 "Fundamentals of Information Security system Design" 10th week IPC mechanism under Linux

Source: Internet
Author: User
Tags function prototype message queue

2017-2018-1 20155222 "Fundamentals of Information Security system Design" 10th week IPC mechanism under Linux

The communication mechanism between multiple processes under Linux is called IPC (inter-process Communication), which is a way of communicating with each other across multiple processes. There are several ways of interprocess communication under Linux: Half-duplex pipes, Named pipes, message queues, signals, semaphores, shared memory, memory-mapped files, sockets, and so on. Using these mechanisms can provide a flexible and robust framework for Web server development under Linux.

The above content is quoted from CSDN

Shared memory

Shared memory is a process of communication between multiple processes that share memory areas, a special range of addresses created by IPC for a process, which will appear in the address space of the process (where is the address space specifically?). In Other processes can connect the same piece of shared memory to their own address space. All processes can access addresses in shared memory as if they were allocated by malloc. If a process writes data to the shared memory, the changes are immediately visible to other processes.
Shared memory is the fastest way to IPC because there is no intermediate process for communicating with shared memory, and pipelines, message queues, and so on, require that the data be transformed through an intermediary mechanism. The shared memory method directly maps a segment of memory, and the shared memory between multiple processes is the same block of physical space, which is mapped only to the different addresses of the processes, so there is no need to replicate and can use this space directly.
Note: The shared memory itself does not have a synchronization mechanism and needs to be controlled by the programmer.

Shared Memory header file:

#include <sys/types.h>   #include <sys/stat.h>  #include <sys/shm.h>   

Structure SHMID_DS structure (not very familiar, look at the MSGID_DS structure of Message Queuing):

strcut shmid_ds{      struct ipc_perm    shm_perm;      size_t    shm_segsz;      time_t    shm_atime;      time_t    shm_dtime;      ......  }  

Shared Memory function Definitions:

int shmget(key_t key,size_t size,int shmflg);  //shmget函数用来创建一个新的共享内存段, 或者访问一个现有的共享内存段(不同进程只要key值相同即可访问同一共享内存段)。第一个参数key是ftok生成的键值,第二个参数size为共享内存的大小,第三个参数sem_flags是打开共享内存的方式。  eg.int shmid = shmget(key, 1024, IPC_CREATE | IPC_EXCL | 0666);//第三个参数参考消息队列int msgget(key_t key,int msgflag);  void *shmat(int shm_id,const void *shm_addr,int shmflg); //shmat函数通过shm_id将共享内存连接到进程的地址空间中。第二个参数可以由用户指定共享内存映射到进程空间的地址,shm_addr如果为0,则由内核试着查找一个未映射的区域。返回值为共享内存映射的地址。  eg.char *shms = (char *)shmat(shmid, 0, 0);//shmid由shmget获得  int shmdt(const void *shm_addr); //shmdt函数将共享内存从当前进程中分离。 参数为共享内存映射的地址。  eg.shmdt(shms);  int shmctl(int shm_id,int cmd,struct shmid_ds *buf);//shmctl函数是控制函数,使用方法和消息队列msgctl()函数调用完全类似。参数一shm_id是共享内存的句柄,cmd是向共享内存发送的命令,最后一个参数buf是向共享内存发送命令的参数。
Pipeline

A pipeline is actually a piece of shared memory used for interprocess communication, and the process of creating a pipeline is called a pipe server, and the process connecting to a pipeline is a pipe client. Once a process has written data to the pipeline, another process can read it from the other end of the pipeline.
Features of the piping:
1, the pipeline is half-duplex, the data can only flow in one direction, the need for both sides to communicate, need to establish two pipelines;
2. Can only be used between parent-child processes or sibling processes (affinity processes). For example, a new process created by fork or exec, when using exec to create a new process, you need to pass the pipe's file descriptor as a parameter to the new process created by exec. When the parent process communicates directly with a child process created using fork, the process that sends the data closes the read end, and the process that accepts the data closes the write end.
3, separate form a separate file system: pipeline for the process at both ends of the pipeline is a file, but it is not an ordinary file, it does not belong to a file system, but on its own, constitute a file system, and only exist with memory.
4. Read and write data: a process that writes to the pipeline is read out by the process at the other end of the pipeline. The content that is written is added to the end of the pipe buffer every time, and the data is read from the head of the buffer each time.
The implementation mechanism of the pipeline:
A pipeline is a buffer that is managed by the kernel, which is the equivalent of a note we put into memory. One end of the pipeline connects to the output of a process. This process will put information into the pipeline. The other end of the pipeline connects to the input of a process that takes out the information that is put into the pipeline. A buffer does not need to be large, it is designed to be a circular data structure so that the pipeline can be recycled. When there is no information in the pipeline, the process read from the pipeline waits until the process at the other end puts the information. When the pipeline is filled with information, the process that tries to put it in will wait until the process on the other side takes out the information. When all two processes are terminated, the pipeline disappears automatically.
Pipelines can only be used on the local computer and not for communication between networks.

Pipe function Prototype:

#include <unistd.h>   int pipe(int file_descriptor[2]);//建立管道,该函数在数组上填上两个新的文件描述符后返回0,失败返回-1。  eg.int fd[2]  

Access to data by using the underlying read and write notes. Write data to file_descriptor[1] and read the data from the file_descriptor[0]. The sequential principle of writing and reading is FIFO.
Pipe reading and writing rules
When there is no data to read
O_nonblock Disable:read Call blocking, that is, the process pauses execution until the data arrives.
The O_nonblock enable:read call returns a -1,errno value of Eagain.
When the pipes are full
O_nonblock Disable:write call blocked until a process reads the data.
O_nonblock Enable: Call returns -1,errno value of Eagain
Read returns 0 if the corresponding file descriptor for all pipe writes is closed
The write operation generates a signal if the file descriptor corresponding to the read end of all the pipes is closed sigpipe
When the amount of data to be written is not greater than PIPE_BUF (posix.1 requires pipe_buf at least 512 bytes), Linux guarantees the atomicity of the write.
When the amount of data to be written is greater than Pipe_buf, Linux will no longer guarantee the atomicity of writes.

Named Pipes (FIFO)

A named pipe is a special type of file that exists as a file in the system. This overcomes the drawbacks of the pipeline, and he can allow inter-process communication without affinity.
Create two system call prototypes for the pipeline:

#include <sys/types.h>   #include <sys/stat.h>   int mkfifo(const char *filename,mode_t mode); //建立一个名字为filename的命名管道,参数mode为该文件的权限(mode%~umask),若成功则返回0,否则返回-1,错误原因存于errno中。  eg.mkfifo( "/tmp/cmd_pipe", S_IFIFO | 0666 );  

How to do this is done by creating a named pipe and then using system calls such as open, read, write, and so on. Creation can be created manually or in a program.

int mknod(const char *path, mode_t mode, dev_t dev); //第一个参数表示你要创建的文件的名称,第二个参数表示文件类型,第三个参数表示该文件对应的设备文件的设备号。只有当文件类型为 S_IFCHR 或 S_IFBLK 的时候该文件才有设备号,创建普通文件时传入0即可。  eg.mknod(FIFO_FILE,S_IFIFO|0666,0);    

The difference between a pipe and a named pipe:
For a named pipe FIFO, the IO operation is basically the same as the normal pipe IO operation, but there is a major difference between the two, in a named pipe, the pipeline can have been created beforehand, such as we do at the command line
Mkfifo Myfifo
is to create a named channel, we must use the Open function to display the channel to connect to the pipeline, and in the pipeline, the pipeline has been created in the main process, and then when the fork directly copy the relevant data or a new process created by Exec, the pipeline file descriptor when the parameters are passed in.
In general, FIFO and pipe are always in a blocking state. That is, if Read permission is set when the named pipe FIFO is open, the read process will block until the other process opens the FIFO and writes the data to the pipeline. This blocking action, in turn, is also true. If you do not want the named pipe operation to be blocked, you can use the O_NONBLOCK flag when open to turn off the default blocking operation.

Signal (signal)
#include <sys/types.h>   #include <signal.h>   void (*signal(int sig,void (*func)(int)))(int); //用于截取系统信号,第一个参数为信号,第二个参数为对此信号挂接用户自己的处理函数指针。返回值为以前信号处理程序的指针。  eg.int ret = signal(SIGSTOP, sig_handle);  

Because signal is not robust enough, the Sigaction function is recommended.

int kill(pid_t pid,int sig); //kill函数向进程号为pid的进程发送信号,信号值为sig。当pid为0时,向当前系统的所有进程发送信号sig。  int raise(int sig);//向当前进程中自举一个信号sig, 即向当前进程发送信号。  #include <unistd.h>   unsigned int alarm(unsigned int seconds); //alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。使用alarm函数的时候要注意alarm函数的覆盖性,即在一个进程中采用一次alarm函数则该进程之前的alarm函数将失效。  
Messages Queue (message queues)

Message Queuing is an internal linked list in the kernel address space through which content is passed directly through the Linux kernel, messages are sent sequentially to the message queue, and obtained from the queue in several different ways, and each message queue can be uniquely identified with an IPC identifier. Message Queuing in the kernel is distinguished by the IPC identifier, and the different message queues are directly independent of each other. The messages in each message queue form a separate linked list.
Message Queuing overcomes the lack of signal-carrying information, and pipelines can only host unformatted character streams.
Message Queue header file:

#include <sys/types.h>   #include <sys/stat.h>   #include <sys/msg.h>   

Message buffer structure:

struct msgbuf{      long mtype;      char mtext[1];//柔性数组  };  

There are two members in the structure, Mtype is the message type, the user can set a message type, can send and accept their own message correctly in the message queue. Mtext is the message data, using a flexible array, the user can redefine the MSGBUF structure. For example:

struct msgbuf{      long mtype;      char mtext[1];//柔性数组  };

Of course, the user can not arbitrarily define the MSGBUF structure, because the size of the message in Linux is limited, defined in the Linux/msg.h as follows:

Define Msgmax 8192

The total message size cannot exceed 8,192 bytes, including the Mtype member (4 bytes).
2. Msqid_ds Kernel data structure

struct msgid_ds{    struct ipc_perm msg_perm;    time_t msg_stime;    time_t msg_rtime;    time_t msg_ctime;    unsigned long _msg_cbuyes;    ..........};

In the Linux kernel, each message queue maintains a struct that holds the message queue's current state information, which is defined in the header file linux/msg.h.
3. Ipc_perm Kernel data structure

struct ipc_perm{    key_t key;    uid_t uid;    gid_t gid;    .......  

The structure Ipc_perm holds some important information about Message Queuing, such as the key value associated with the message queue, the user ID group ID of the message queue, and so on. It is defined in the header file linux/ipc.h.
Common functions:
An ID value must be specified when the system establishes an IPC communication (Message Queuing, semaphores, and shared memory). Typically, this ID value is obtained through the Ftok function.

key_t Ftok (const char * fname, int id);//parameter one is directory name, parameter two is ID.  If the specified file has an index node number of 65538, converted to 16 in 0x010002, and you specify an ID value of 38, converted to 16 0x26, then the last key_t return value is 0x26010002.  eg.key_t key = Key =ftok (".", 1); int Msgget (key_t key,int msgflag); Msgget is used to create and access a message queue.  The program must provide a key value to name a particular message queue. Eg.int msg_id = Msgget (Key, Ipc_create | Ipc_excl |  0x0666);//Create a new queue (Ipc_create) based on the keyword, if there is an error in the queue (IPC_EXCL), have read and write execution permissions to the file (0666). int msgsnd (int msgid,const void *msgptr,size_t msg_sz,int MSGFLG); The MSGSND function allows us to add a message to the message queue.   Msgptr just want to prepare a pointer to send the message, the pointer struct must start with a long integer variable.      eg.struct msgmbuf{int mtype;  Char mtext[10];  };  struct MSGMBUF msg_mbuf;  Msg_mbuf.mtype = 10;//message size 10 bytes memcpy (msg_mbuf.mtext, "test message", sizeof ("test Message"));  int ret = MSGSND (msg_id, &msg_mbuf, sizeof ("test message"), ipc_nowait); int MSGRCV (int msgid, void *msgptr, size_t msg_sz, long int msgtype, int msgflg); MSGRCV can receive operations on a specified message queue through Msqid.  The second parameter is the message buffer variable address, the third parameter is the message buffer structure size, but does not include the Mtype member length, and the fourth parameter is mtype specifies the type of message to get from the queue. eg.int ret = MSGRCV (msg_id, &msg_mbuf, 10, 10,ipc_nowait |  MSG_NOERROR); int msgctl (int msqid,int cmd,struct msqid_ds *buf); The MSGCTL function is mainly to control operations such as deleting message queues.  The CMD value is as follows: Ipc_stat: Gets the MSGID_DS structure of the queue and saves it to the address buf points to.  Ipc_set: Sets the msgid_ds of the queue to the Msgid_ds that buf points to.   Ipc_rmid: The kernel deletes Message Queuing, the last entry is null, and after the operation, the kernel removes the message queue from the system.

The nature of Message Queuing
Linux Message Queuing (queue) is essentially a linked list that has a message queue identifier (queue ID). Msgget creates a new queue or opens an existing queue, MSGSND adds a new message to the end of the queue, MSGRCV takes a message from the queue, does not necessarily follow FIFO, or can fetch messages by the Type field of the message.

Comparison of Message Queuing and named pipes
Message Queuing is much the same as named Pipes, where the process of communicating Message Queuing, like a named pipe, can be unrelated processes, and they all pass data in a way that is sent and received. In a named pipe, send data with write, receive data with read, then in message queue, send data with MSGSND, receive data with MSGRCV. And they have a maximum length limit for each data.
The advantage of Message Queuing over named Pipes is that 1, Message Queuing can also exist independently of the send and receive processes, eliminating the difficulties that can arise when synchronizing named Pipes for opening and closing. 2. By sending messages, you can also avoid the synchronization and blocking problems of named pipes, and do not need to provide synchronization methods by the process itself. 3. The receiving program can selectively receive data through the message type, instead of being received only by default, as in a named pipe.

2017-2018-1 20155222 "Fundamentals of Information Security system Design" 10th week IPC mechanism under Linux

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.