Chapter II Communication and Synchronization
Foreword: Way to support multiple processes in Linux / UNIX, mainly include: signal, semaphore, message queue, shared memory, pipe (including unnameless pipes and FIFO) is also a way to communicate between processes.
· Capture and processing of 2, 2 signals:
#inlucde
related functions:
SigAction (int Signo, Const Struct SigAction * ACT, STRUCT SIGACTION * OACT); // Setting Signal Processor
Struct sigaction {
Void (* sa_handler) ();
Sigset_t sa_mask;
INT SA_FLAGS;
}
(1) Signal processor function pointer (2) Signal set (3) Signal processor's flag (access manual)
INT SIGEMPTYSET (SIGSET-T * SET); / / Signal Collection Clear
INT SIGFILLSET (SIGSET_T * SET); // Settings the complete works containing all signals
INT SigaddSet (SIGSET_T * SET, INT SIGNO); // Add a signal to the signal collection
INT Sigdelset (SIGSET_T * SET, INT SIGNO); // Remove a signal from the collection
INT Sigismember (const sigset_t * set, int sign); // Decision signal is included in a given collection
INT SigProcmask (int how, const sigset_t * set, sigset_t * et); // Setting process interrupt shielding code
How = [SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK], * OSET to make a backup
Use the signal processor basic method:
Written signal processing function handler_sigproc ();
// The signal processing function is executed, remembers the signal to be cleaved.
// sigaddset (& blockmask, sigint); // signal processor default signals
// sigaddset (& blockmask, sigterm); / / signal processor processing
// SigProcmask (SIG_BLOCK, & blockmask, null); // Confusion signal
2. Set the Signal Processor Struction ACT;
Act.sa_handler = handler_sigproc;
SiGemptySet (Act.sa_mask);
sigaddset (& act.sa_mask, sigterm); // Blocked the corresponding signal during execution of the signal processor
SigAction (SIGTERM, & ACT, NULL); // Generate (kill) Termination Signal Add ACT Signal Processor
Express system call, slow system calls may be interrupted, POSIX.1 returns -1 -1, and errno is set to Einter, as long as "atomic operation" may be interrupted, pay attention to this type of problem Fault tolerance:
RET = Read (FD, BUF, 255);
if (RET == -1 && errno == Einter) // If the system call is caused by the implementation of the interrupt) ......
· 2.3 semaphore
The famous semaphore is a whole game, just know that its name can be used;
The unnamed signal is part, can only be used by inheritance;
related functions:
Header file:
INT SemctL (int SEM_ID, INT SEMNUM, INT CMD); // Semic Semic Control Function (Value / Delete / Setting, etc.)
INT Semop (Int Semid, Struct Sembuf * SOPS, INT NSOPS); // Semic Semic Operation Function
(1) How to operate the signal volume group ID (2) (3) number of operations
Struct sembuf {
Short sem_num; / / Operation of the semicomposition of the semi-semger Sem_NUM
Short sem_op; // Execute -1 is P operation to the semger SEM_VALUE, 1 is V operation
Short Sem_flg; // Usually takes 0, if the SEM_UNDO exits the process, the signal value becomes 0
}
Using the quantile flow: 1. SEM_ID = Semget (SEM_KEY, 0, 0); // SEM_KEY custom, to ensure uniqueness
2. IF (SEM_ID! = -1) // If the quantity group does not exist
SEM_ID = SEMGET (SEM_KEY, SEM_NUM, IPC_CREAT | IPC_EXCL | 0666)
... // Create a resource for a sem_num, permission is 0666 (readable and writable)
ELSE initialization signal volume number of semaphore
3 implementation P and V operation functions:
Void P (int SEM_NUM, INT SEM_ID) // Sem_NUM Sem_ID of Signal Group SEM_ID
{
Struct Sembuf SEM [1];
SEM [0] .SEM_NUM = SEM_NUM; SEM [0] .SEM_OP = -1; SEM [0] .SEM_FLG = 0;
IF (SEMOP (SEM_ID, SEM, 1) == -1) // ... execute a P operation, V operation is similar
}
4 SemCTL (SEM_ID, SEM_INDEX, IPC_RMID); / / Manually delete semaphore
// Note the difference between "Signal Group" and "Signal Value"!
· 2.4 Message Queue
#include
INT msgget (key_t key, int msgflg); // Create or get the ID of the message queue, and the signal quantity group
INT MSGCTL (int MSQID, int CMD, Struct MSQID_DS * BUF);
INT MSGSND (int MSQID, Void * MSGP, SIZE_T MSGSZ, INT MSGFLG);
INT MSGRCV (int msqid, void * msgp, size_t msgsz, long int msgtyp, int msgflg); // receive messages
// msgtyp = 0: Return the first message> 0: Return the first value = MSGTYP message <0: Return the first value <= - MSGTYP
The basic principle of the use of the message queue:
Sub-process Child Sends the first registration flag FLAG (MSGTYP> 0) and the Child process number to server process server registration, using MSGRCV (Q_MSG_Key, & Recv_buf, Sizeof (Message) -Sizeof (Long), FLAG, 0) in Server segment, Message text does not include the sign of the message head. The server is then sent to the Server process number, the received message flag is received to the child process number to represent the previous message. ---------------------------------------
Message send_msg; // I register and submit the ID of this process
Send_msg.m_type = flag;
Send_msg.process_id = getPid ();
Send_len = SizeOf (long) sizeof (int);
Ret = msgsnd (MSQ_Key, & send_msg, send_len, 0);
Message Recv_msg, reply_msg;
/ / Receive message for flag FLAG
RET = MSGRCV (MSQ_Key, & Recv_msg, Sizeof (Message) -sizeof (long), getPid (), FLAG, 0);
Reply_msg.m_type = rv_msg.process_id; // Send feedback messages to sub-process
Reply_msg.process_id = getPid () // tells the sub-process server server process number, ready to establish interaction
The message queue communicates through the message flag (ie process number). If the client / server process is exited, the message is lost. That is, the message that exits one party as a flag will not be received by any process, as other process numbers and message flags do not match.
· 2.5 Sharing memory
Shared memory is a plurality of processes sharing one end physical memory space, and the message queue is copied from the application buffer to the core buffer by putting a physical memory address. Therefore, the communication usage efficiency of the shared memory is higher than the message queue, but there is a complex synchronous mutex.
function:
int shMget ((key_t key, int size, int shmflg); // Create or get a shared memory
INT Shmctl ((int shmid, int cmd, struct shmid_ds * buf); // Share memory operation
Void * Shmat ((int shmid, const void * shmaddr, int shmflg)); // Get a pointer to shared memory
INT SHMDT ((const void * shmaddr); // Separate / delete shared memory blocks from the process
·summary:
Message queues can be multiplexed, and inter-process synchronization does not require complex synchronization mutual exclusion. Data is passed in a stream,
Each news is independent and can distinguish. The specific semantics of information requires the process of receiving both ends to define and explains themselves. Dispense
The disadvantage of the group is that two data copies are required, from the user space to the core, from core to user space.
Shared memory does not need multiple copies, in synchronization between the data larger, the shared memory can improve efficiency,
However, complex processes are needed to synchronize mutual exclusion.
· 2.5 Sharing memory
Shared memory is a plurality of processes sharing one end physical memory space, and the message queue is copied from the application buffer to the core buffer by putting a physical memory address. Therefore, the communication usage efficiency of the shared memory is higher than the message queue, but there is a complex synchronous mutex. function:
int shMget ((key_t key, int size, int shmflg); // Create or get a shared memory
INT Shmctl ((int shmid, int cmd, struct shmid_ds * buf); // Share memory operation
Void * Shmat ((int shmid, const void * shmaddr, int shmflg)); // Get a pointer to shared memory
INT SHMDT ((const void * shmaddr); // Separate / delete shared memory blocks from the process
·summary:
Message queues can be multiplexed, and inter-process synchronization does not require complex synchronization mutual exclusion. Data is passed in a stream,
Each news is independent and can distinguish. The specific semantics of information requires the process of receiving both ends to define and explains themselves. Dispense
The disadvantage of the group is that two data copies are required, from the user space to the core, from core to user space.
Shared memory does not need multiple copies, in synchronization between the data larger, the shared memory can improve efficiency,
However, complex processes are needed to synchronize mutual exclusion.