Linux notes--linux Process communication

Source: Internet
Author: User
Tags delete key function prototype posix semaphore set time signal handler terminates

Http://www.cnblogs.com/linshui91/archive/2010/09/29/1838770.html

I. Overview of inter-process communication
Process communication has some of the following purposes:
A, data transfer: A process needs to send its data to another process, the amount of data sent between a byte to a few m bytes
B, shared data: Multiple processes want to manipulate shared data, a process changes the shared data, and other processes should be seen immediately.
C, notification event: A process needs to send a message to another or a set of processes to notify it (they) that an event has occurred (such as notifying the parent process when the process terminates).
D, resource sharing: Multiple processes share the same resources. In order to do this, the kernel is required to provide a lock and synchronization mechanism.
E, Process Control: Some processes want to fully control the execution of another process (such as the debug process), at which point the control process wants to be able to intercept all the sink and exception of another process and be able to know its state change in time.
The Linux interprocess communication (IPC) has been developed in several parts:
Early UNIX interprocess communication, System V based inter-process communication, socket-based interprocess communication, and POSIX interprocess communication.
UNIX inter-process communication methods include: Pipeline, FIFO, signal.
System V interprocess communication methods include: System V Message Queuing, System V Semaphore, System V shared memory,
POSIX interprocess communication includes: POSIX Message Queuing, POSIX semaphore, and POSIX shared memory.
Now, the way Linux uses inter-process communication:
(1) piping (pipe) and well-known piping (FIFO)
(2) signal (signal)
(3) Message Queuing
(4) Shared memory
(5) Signal volume
(6) socket (socket) Two, pipeline communication the normal Linux shell allows redirection, while redirection uses the pipeline. For example:
PS | grep vsftpd. Pipelines are unidirectional, first-out, unstructured, fixed-size byte streams that connect the standard output of one process to the standard input of another process. The write process writes data to the end of the pipeline, and the read process reads the data at the channel end of the pipeline. When the data is read out, it is removed from the pipeline, and no other read process can read the data. The pipeline provides a simple flow control mechanism. When a process attempts to read an empty pipeline, the process blocks until the data is written to the pipeline. Similarly, when the pipeline is full, the process attempts to write the pipeline, and the write process blocks until the other process removes the data from the pipeline. Pipelines are primarily used for communication between different processes.
Pipeline creation and shutdown
Create a simple pipeline that you can use to call pipe (). It takes a parameter, which is an array that consists of two integers. If the system call succeeds, this array will include the two file descriptors used by the pipeline. After you create a pipeline, the process typically produces a new process.
System call: Pipe ();
Prototype: int pipe (int fd[2]);
Return value: Returns 0 if the system call succeeds. If the system call fails, return-1:
Errno=emfile (file descriptor with no empty pro)
Emfile (System File table is full)
Efault (FD array not valid)
Note: fd[0] is used for reading pipelines, fd[1] for writing to pipelines.
See annex for illustration
Creation of pipelines
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>int main ()
{
int pipe_fd[2];
if (pipe (PIPE_FD) <0) {
printf ("Pipe Create error\n");
return-1;
}
Else
printf ("Pipe Create success\n");
Close (pipe_fd[0]);
Close (pipe_fd[1]);
} Pipeline Read and write
Pipelines are primarily used for communication between different processes. In practice, you typically create a pipeline and then create a child process from the fork function. See annex for illustration. Named pipes that are written by the child process and read by the parent process: see the Attachment pipeline read and write considerations:
You can create a two-way pipeline by opening two of pipelines. However, the file descriptor needs to be set correctly in the sub-thread. Pipe () must be called in the system Call fork (), otherwise the child process will not inherit the file descriptor. When using a half-duplex pipeline, any associated processes must share a related ancestor process. Because the pipeline exists in the system kernel, any process that is not in the ancestor process of the process that created the pipeline will not be able to address it. This is not the case in a named pipe. See:pipe_rw.c#include<unistd.h> for examples of pipelines
#include <memory.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>int main ()
{
int pipe_fd[2];
pid_t pid;
Char buf_r[100];
char* P_wbuf;
int R_num;memset (buf_r,0,sizeof (Buf_r)); The data in the array is clear 0;if (pipe (PIPE_FD) <0) {
printf ("Pipe Create error\n");
return-1;
}if ((Pid=fork ()) ==0) {
printf ("\ n");
Close (pipe_fd[1]);
Sleep (2);
if ((R_num=read (pipe_fd[0],buf_r,100)) >0) {
printf ("%d numbers read from being pipe is%s\n", r_num,buf_r);
}
Close (pipe_fd[0]);
Exit (0);
}else if (pid>0) {
Close (pipe_fd[0]);
if (write (pipe_fd[1], "Hello", 5)!=-1)
printf ("Parent write success!\n");
if (write (pipe_fd[1], "pipe", 5)!=-1)
printf ("Parent wirte2 succes!\n");
Close (pipe_fd[1]);
Sleep (3);
Waitpid (pid,null,0);
Exit (0);
}
}
Standard Flow Piping
As with standard I/O for file streams in Linux, the operation of pipelines also supports file stream based patterns. The interface functions are as follows:
Library functions: Popen ();
Prototype: FILE *open (char *command,char *type);
Return value: If successful, a new file stream is returned. Returns null if the process or pipeline cannot be created. The direction of the data flow in the pipeline is controlled by the second parameter type. This parameter can be either R or W, which represents read or write, respectively. But not both for reading and writing. Under the Linux system, the pipeline opens as the first character in the parameter type represents. So, if you write RW in the parameter type, the pipe will open in a read way. Pipelines created with Popen () must be closed with pclose (). In fact, Popen/pclose is very similar to fopen ()/fclose () in the standard file input/output stream.
Library functions: Pclose ();
Prototype: int pclose (FILE *stream);
Return value: Returns the state of the system call WAIT4 ().
Returns 1 if the stream is invalid, or if the system call WAIT4 () fails. Note This library function waits for the pipeline process to finish running, and then closes the file stream. The library function Pclose () executes the WAIT4 () function on a process created with Popen (), which destroys the pipeline and the file system.
Example of a flow pipeline.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#define BUFSIZE 1024
int main () {
FILE *FP;
Char *cmd= "PS-EF";
Char Buf[bufsize];
buf[bufsize]= ' + ';
if ((Fp=popen (cmd, "R")) ==null)
Perror ("Popen");
while ((Fgets (BUF,BUFSIZE,FP))!=null)
printf ("%s", buf);
Pclose (FP);
Exit (0);
} Named Pipes (FIFO)
Basic concepts
Named Pipes are basically the same as normal pipes, but there are some notable differences:
A, named pipes exist in the file system as a special device file.
B, different ancestors of the process can be shared through the pipeline data.
C, when the shared pipeline process finishes performing all I/O operations, the named pipe will continue to be saved in the file system for later use.
Pipelines can only be used by related processes, and their common ancestor processes create pipelines. However, with FIFO, unrelated processes can also exchange data. Named pipe creation and operation
Named pipe creation
#include <sys/types.h>
#include <sys/stat.h>
int Mkfifo (const char *pathname,mode_t mode);
Returns: 0 if successful, 1 if error is returned
Once you have created a FIFO with MKFIFO, you can open it by opening it. Indeed, general file I/O functions (close,read,write,unlink, etc.) are available for FIFO. When a FIFO is opened, the non-blocking flag (O_nonblock) has the following effects:
(1) in the general case (without stating O_nonblock), read-only open to block to some other process to open this FIFO for write. Similarly, opening a FIFO for writing to block to some other process opens it for reading.
(2) If a o_nonblock is referred to, the read-only open returns immediately. However, if no process has opened a FIFO for reading, then write-only open will return an error and its errno is Enxio. Similar to a pipeline, if you write a FIFO that does not yet have a process open for reading, it generates a signal sigpipe. If the FIFO is closed by the last write process of a FIFO, a file end flag is generated for the read process of the FIFO.
FIFO Related error message:
Eacces (No access)
Eexist (The specified file does not exist)
Enametoolong (path name is too long)
ENOENT (contains a directory that does not exist)
ENOSPC (Insufficient file system space)
Enotdir (Invalid file path)
Erofs (The specified file exists in the read-only file system) fifo_write.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FIFO "/tmp/myfifo" main (int argc,char** argv)
{
Char buf_r[100];
int FD;
int nread;
if (Mkfifo (fifo,o_creat| O_EXCL) <0) && (errno!=eexist))
printf ("Cannot create fifoserver\n");
printf ("Preparing for Reading bytes....\n");
memset (buf_r,0,sizeof (buf_r));
Fd=open (fifo,o_rdonly| o_nonblock,0);
if (fd==-1)
{
Perror ("open");
Exit (1);
}
while (1) {
memset (buf_r,0,sizeof (buf_r));
if ((Nread=read (fd,buf_r,100)) ==-1) {
if (Errno==eagain)
printf ("No Data yet\n");
}
printf ("Read%s from fifo\n", buf_r);
Sleep (1);
}
Pause ();
Unlink (FIFO);
}fifo_read.c
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Fifo_server "/tmp/myfifo"
Main (int argc,char** argv)
{
int FD;
Char w_buf[100];
int nwrite;
if (fd==-1)
if (Errno==enxio)
printf ("Open error;no reading process\n");
Fd=open (fifo_server,o_wronly| o_nonblock,0);
if (argc==1)
printf ("Please send something\n");
strcpy (w_buf,argv[1]);
if ((Nwrite=write (fd,w_buf,100)) ==-1)
{
if (Errno==eagain)
printf ("The FIFO has not been read yet. Please try later\n ");
}
Else
printf ("Write%s to the fifo\n", w_buf);
}
Third, the signal
Signal overview
The signal is a software interrupt. The signaling (signal) mechanism is the signaling mechanism between the oldest processes in Unix systems. It is used to pass asynchronous signals between one or more processes. Many conditions can produce a signal.
A, when the user presses certain terminal key, produces the signal. Pressing the DELETE key on the terminal usually generates an interrupt signal (SIGINT). This is the way to stop a program that has lost control.
B, hardware abnormal generation signal: Divisor is 0, invalid storage access and so on. These conditions are usually detected by the hardware and notified to the kernel. The kernel then generates the appropriate signal for the process that is running when the condition occurs. For example, a SIGSEGV is generated for a process that performs an invalid storage access.
C, the process uses the Kill (2) function to send a signal to another process or process group. Naturally, there are some limitations: all of the incoming and outgoing signal processes must be the same, or the owner of the sending signal process must be superuser.
D, the user can use the Kill (ID value) command to send the signal to other processes. This program is the interface of the KILL function. This command is commonly used to terminate a runaway background process.
E, a signal is also generated when a software condition has been detected and notified of the process. This does not refer to hardware conditions (such as being removed by 0), but software conditions. For example, Sigurg (data that does not have a specified baud rate on a network connection), Sigpipe (a process writes this pipeline after the pipeline's read process has been terminated), and SIGALRM (the time the alarm set by the process has timed out). The kernel produces signals for the process to respond to different events, which are the source of the signal. The main signal sources are as follows:
(1) Exception: An exception occurred during the process operation;
(2) Other processes: One process can send signals to another or a set of processes;
(3) terminal interruption: ctrl-c,ctro-\, etc.;
(4) Operation control: Front desk, background process management;
(5) Allocation amount: CPU timeout or file size breakthrough limit;
(6) Notice: Notify the process of an event occurred, such as I/o ready, etc.;
(7) Alarm: Timer expires, signal in Linux
1, SIGHUP 2, SIGINT (termination) 3, Sigquit (exit) 4, Sigill 5, SIGTRAP 6, Sigiot 7, Sigbus 8, SIGFPE 9, SIGKILL 10, Siguser 11, SIGSEGV SI Guser 12, Sigpipe 13, Sigalrm 14, SIGTERM 15, SIGCHLD 16, Sigcont 17, SIGSTOP 18, SIGTSTP 19, Sigttin 20, Sigttou 21, Sigurg 22, SIG Xcpu 23, Sigxfsz 24, Sigvtalrm 25, Sigprof 26, Sigwinch 27, SIGIO 28, SIGPWR commonly used signals:
SIGHUP: An end signal emitted from the terminal;
SIGINT: Interrupt signal from the keyboard (CTRL + C)
Sigquit: Exit signal from the keyboard;
SIGFPE: Floating-point anomaly signal (for example, floating-point arithmetic overflow);
SIGKILL: The signal ends the process of receiving signals;
SIGALRM: When the timer of the process expires, the signal is sent;
A signal produced by the Sigterm:kill command;
SIGCHLD: A signal that identifies the stop or end of a child process;
SIGSTOP: Stop sweep signals from the keyboard (CTRL-Z) or debugger can require the system to operate in one of the following three ways when a signal appears.
(1) Ignore this signal. Most signals can be processed in this way, but there are two types of signals that must never be ignored. They are: Sigkill and sigstop. These two types of signals cannot be ignored because they provide a reliable way for the superuser to terminate or stop the process. In addition, if some signal generated by a hardware exception is omitted (such as illegal storage access or divided by 0), the behavior of the process is shown as defined.
(2) Capture the signal. To do this, notify the kernel to call a user function when a signal occurs. In the user function, the user is expected to perform the processing of this event. If the SIGCHLD signal is captured, it indicates that the child process has terminated, so the capture function of this signal can call Waitpid to get the process ID of the child process and its terminating state.
(3) Perform the system default action. The system default action for most signals is to terminate the process. Each signal has a default action, which is the kernel's handling of the signal when the process does not specify a handler for the signal. There are 5 types of default actions:
(1) Abnormal termination (abort): In the current directory of the process, the address space contents of the process, register content to a file called core, and then terminate the process.
(2) Exit: does not produce a core file and terminates the process directly.
(3) Ignore (ignore): ignore the signal.
(4) Stop (stop): suspends the process.
(5) Continue (Contiune): If the process is suspended, the dynamic line of the process is just resumed. Otherwise, the signal is ignored. Sending and capturing of signals
Kill () and raise ()
Kill () can not only abort the process, but also send other signals to the process.
Unlike the Kill function, the raise () function runs to send a signal to the process itself
#include <sys/types.h>
#include <signal.h>
int Kill (pid_t pid,int Signo);
int raise (int signo);
Two function returns: 0 if successful, or 1 if an error occurs.
There are four different conditions for the PID parameter of Kill:
(1) pid>0 sends the signal to a process with a process ID of PID.
(2) pid==0 sends the signal to its Process group ID equal to the process group ID of the sending process, and the sending process has all the processes to which it is allowed to send a signal.
(3) pid<0 sends the signal to its Process group ID equal to the PID absolute value, and the sending process has permission to send a signal to all processes. As mentioned above, "All processes" do not include processes in the system process set.
(4) pid==-1 posix.1 undefined case
Kill.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
int main ()
{
pid_t pid;
int ret;
if ((Pid==fork ()) <0) {
Perro ("fork");
Exit (1);
}
if (pid==0) {
Raise (SIGSTOP);
Exit (0);
}else {
printf ("pid=%d\n", PID);
if ((Waitpid (Pid,null,wnohang)) ==0) {
if ((Ret=kill (Pid,sigkill)) ==0)
printf ("Kill%d\n", PID);
else{
Perror ("Kill");
}
}
}
}alarm and Pause functions
Use the alarm function to set a time value (alarm time) that will be exceeded at some point in the future time value. When the set time is exceeded, a SIGALRM signal is generated. If you do not ignore or do not capture the lead signal, its default action is to terminate the process.
#include <unistd.h>
unsigned int alarm (unsigned int secondss);
Returns the number of seconds remaining for the alarm time set by 0 or earlier. The value of the parameter seconds is the number of seconds after which the signal SIGALRM is generated after the specified seconds seconds. Each process can have only one alarm time. If an alarm time has been set for the process before calling alarm, and it has not timed out, the remaining value of the alarm time is returned as the value of the alarm function call. The previously registered alarm time is replaced by the new value.
If there is a previously registered alarm time that has not been exceeded, and the seconds value is 0, the previous alarm time is canceled and the remaining values remain as the function's return value.
The pause function hangs with the calling process until a signal is captured
#include <unistd.h>
int pause (void);
Return: -1,errno set to Eintr
Pause returns only if a signal handler is executed and returned from it. Alarm.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int ret;
Ret=alarm (5);
Pause ();
printf ("I have been Waken up.\n", ret);
} Processing of Signals
When a signal is captured by the system, either ignore the signal or use the specified processing function to process the signal, or use the system default mode. There are two main ways of signal processing, one is to use a simple signal function, and one is to use a set of signal set functions.
Signal ()
#include <signal.h>
void (*signal (int signo,void (*FUNC) (int)))) (int)
Return: Success is the previous signal processing configuration, if the error is Sig_err
The value of Func is: (a) constant sigign, or (b) constant SIGDFL, or (c) the address of the function to invoke when the signal is received. If Sigign is specified, this signal is ignored to the kernel (there are two signals Sigkill and sigstop cannot be ignored). If SIGDFL is specified, the action that is received after this signal is the system default action. When a function address is specified, we call this the capture signal. We call this function a signal handler (signal handler) or a signal capture function (signal-catching funcgion). The signal function prototype is too complex to be simplified if you use the following typedef.
type void sign (int);
Sign *signal (Int,handler *);
See Example: MYSIGNAL.C
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void My_func (int sign_no)
{
if (sign_no==sigint)
printf ("I have get sigint\n");
else if (sign_no==sigquit)
printf ("I have get sigquit\n");
}
int main ()
{
printf ("Waiting for signal SIGINT or sigquti\n");
Signal (SIGINT,MY_FUNC);
Signal (SIGQUIT,MY_FUNC);
Pasue ();
Exit (0);
}
Signal Set Function Group
We need to have a data type that can represent multiple signals-the signal set (signal set). This data type will be used in functions such as sigprocmask () to tell the kernel that the signal in the signal set is not allowed to occur. The signal Set function group contains several modules of water quantity: creating function set, registering signal set, detecting signal set.
See annex for illustration. Create a set of functions
#include <signal.h>
int Sigemptyset (sigset_t* set);
int Sigfillset (sigset_t* set);
int Sigaddset (sigset_t* set,int signo);
int Sigdelset (sigset_t* set,int signo);
Four functions return: 0 If successful, or 1 if there is an error
int Sigismember (const sigset_t* set,int signo);
Return: If True is 1, if False is 0;
Signemptyset: Initialization signal set is empty.
Sigfillset: Initializes the set of signals for all signal sets.
Sigaddset: Adds the specified signal to the existing set.
Sigdelset: Removes the specified signal from the signal set.
Sigismember: Queries whether the specified signal is in the signal set. Register a signal set
The registration signal processor is mainly used to determine how the process handles the signal. The first step is to determine whether the current process block can be passed to the signal set. This first uses the Sigprocmask function to determine the detection or change of the signal mask word, and then uses the Sigaction function to change the behavior of the process after receiving a particular signal.
The signal mask for a process can specify the set of signals that are currently blocked and cannot be delivered to the process. The call function Sigprocmask can detect or change the signal screen word of the process (or both).
#include <signal.h>
int sigprocmask (int how,const sigset_t* set,sigset_t* oset);
Returns: 0 if successful, or 1 if there is an error
The Oset is a non-null pointer, and the process is the current signal shield word returned through Oset. Second, if set is a non-null pointer, how does the parameter indicate how to modify the current signal mask word.
A method for changing the current signal screen word with sigprocmask. How parameter settings:
Sig_block the process a new signal-shielding word is the set of its current signal-shielding word and set-pointing signal set. The set contains additional signals that we want to block.
Sig_nublock the process a new signal-shielding word is the intersection of its current signal-shielding word and set-pointing signal set. The set contains the signals we want to unblock.
Sig_setmask the process a new signal mask is the value that the set points to. If set is a null pointer, it does not change the signal screen word of the process, and the value of how is meaningless.
The function of the Sigaction function is to examine or modify (or both) the processing action associated with the specified signal. This function replaces the signal function used by earlier versions of UNIX.
#include <signal.h>
int sigaction (int signo,const struct sigaction* act,struct sigaction* oact);
Returns: 0 if successful, or 1 if there is an error
The parameter signo is the number of the signal to detect or modify a specific action. If the act pointer is not empty, modify its action. If the oact pointer is empty, the system returns the original action of the signal. This function uses the following structure:
struct sigaction{
void (*sa_handler) (int signo);
sigset_t Sa_mask;
int sa_flags;
void (*sa_restore);
};
Sa_handler is a function pointer that specifies the signal correlation function, which can be a custom handler function, and can also be sig_def or sig_ign;
Sa_mask is a set of signals that specifies which signals should be blocked during the execution of a signal processing program.
The sa_flags contains many flag bits and is a variety of options for processing signals. Specific as follows:
Sa_nodefer\sa_nomask: When this signal is captured, the system does not automatically block the signal when it executes its signal capture function.
Sa_nocldstop: The process ignores any sigstop, SIGTSTP, Sigttin, and Sigtou signals produced by the child process
Sa_restart: Allows the reboot of the system call to function again.
Sa_oneshot\sa_resethand: The custom signal is executed only once, and the system default action of recovering the signal after execution is complete.
The heartbeat is the next step in signal processing, but it is not required. The Sigpending function runs the process of detecting "pending" signals (the process is unclear about his presence) and further decides what to do with them.
Sigpending returns a set of signals that are blocked from being delivered and currently pending for the calling process.
#include <signal.h>
int sigpending (sigset_t * set);
Returns: 0 if successful, or 1 if there is an error
Examples of signal sets see: SIGACTION.C
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void My_func (int signum) {
printf ("If you want to quit,please try sigquit\n");
}
int main ()
{
sigset_t Set,pendset;
struct Sigaction action1,action2;
if (Sigemptyse (&set) <0)
Perror ("Sigemptyset");
if (Sigaddset (&set,sigquit) <0)
Perror ("Sigaddset");
if (Sigaddset (&set,sigint) <0)
Perror ("Sigaddset");
if (Sigprocmask (sig_block,&set,null) <0)
Perror ("Sigprcmask");
esle{
printf ("blocked\n");
Sleep (5);
}
if (Sigprocmask (sig_unblock,&set,null)
Perror ("Sigprocmask");
Else
printf ("unblock\n");
while (1) {
if (Sigismember (&set,sigint)) {
Sigemptyset (&action1.sa_mask);
Action1.sa_handler=my_func;
Sigaction (Sigint,&action1,null);
}else if (Sigismember (&set,sigquit)) {
Sigemptyset (&action2.sa_mask);
Action2.sa_handler=sig_del;
Sigaction (Sigterm,&action2,null);
}
}
}

Linux notes--linux Process communication

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.