Introduction to FunctionsInclude header file <signal.h> function: The Sigaction function is used to change the behavior of a process after receiving a specific signal. Prototype:
int sigaction (int signum,const struct sigaction *act, struct sigaction); Parameters
The first parameter of the function is the value of the signal, which can be used for any particular valid signal except Sigkill and sigstop (defining its own handler function for these two signals, which will result in a signal installation error) The second parameter is a pointer to an instance of the structure sigaction Sigaction instance, the processing of a specific signal is specified, can be null, the process defaults to signal processing the third parameter oldact the object to hold the original processing of the corresponding signal, you can specify null oldact. Return value: Function returned 0 successfully, failure returned-1
about Sigaction Structural body
It contains the processing of the specified signal, signal transmission information, signal processing function should be blocked in the implementation of what functions, etc.
struct Sigaction {
void (*sa_handler) (int); The signal handler does not accept additional data
void (*sa_sigaction) (int, siginfo_t *, void *),//Signal processing can accept additional data, and Sigqueue is used in conjunction with
sigset_t Sa_ Mask
int sa_flags;//influence signal behavior Sa_siginfo indicates acceptance of data
Void (*sa_restorer) (void);//Discard
};
Note: The callback function handle Sa_handler, sa_sigaction can only be optional. Introduction to Supplemental siginfo_t structure
siginfo_t {
int si_signo; /* Signal Number
* /int si_errno; /* An errno value
* /int si_code; /* Signal Code
* /pid_t si_pid; /* Sending process ID
* /uid_t si_uid; /* Real user ID of sending process
* /int si_status;/* Exit value or signal * *
clock_t si_utime;
/* User Time Consumed * *
clock_t si_stime; /* System Time consumed * *
sigval_t si_value; /* Signal Value
* /int si_int; /* POSIX.1B signal
*/void * si_ptr; /* POSIX.1B signal
*/void * si_addr; /* Memory location which caused fault
* /int si_band; /* Band Event
* /int si_fd; /* File Descriptor */
}
Sample CodeThe most basic usage
void handler (int sig)
{
if (sig = = SIGINT)
{
printf ("Recv a sig=%d\n", Sig)
;
}
int main ()
{
struct sigaction act;
Act.sa_handler = handler;
Sigaction (sigint,&act,null);
while (1);
return 0;
}
Using Sigaction to realize my_signal
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h > #include <string.h> #include <signal.h> void handler (int sig) {printf ("Aloha recv a sig=%d\n", SIG
);
/* * Create a function like the signal function/* __sighandler_t my_signal (int sig, __sighandler_t handler) {struct Sigaction act;
struct Sigaction oldact;
/* Before using a sigaction structure, you need to process the following three members/Act.sa_handler = handler;//Specify a new handler function Sigemptyset (&act.sa_mask);//Set signal mask Word
act.sa_flags = 0; if (Sigaction (SIG, &act, &oldact) < 0)//Registration signal, specify the signal processing information before the signal processing function (including the processing function of the previous signal) return sig_err;//registration failed --Returns SID_ERR return oldact.sa_handler;//registration Success--Returns the signal processing function before the int main (int argc, char *argv[]) {//Simulate Signa
L function my_signal (SIGINT, handler);
for (;;)
{Pause ();
return 0; }
sigqueue function
Function: The new transmission signaling system calls, mainly for real-time signal support signal with parameters, and function sigaction () with the use.
Note: Compared to the kill function, int kill (pid_t pid, int siq) has more arguments
Prototype:
int Sigqueue (pid_t pid, int sig, Const Union Sigval value); Parameters
The 1th parameter of the sigqueue is to specify the process ID to receive the signal, and the 2nd parameter determines the signal to be sent, and the 3rd parameter is a federated data structure Union Sigval, which specifies the signal-passing parameter, which is usually called the 4-byte value. Return value returned 0 successfully, failure returned-1
Sigqueue () passes more additional information than kill (), but Sigqueue () sends a signal to only one process and cannot send a signal to a process group. Sigval Consortium
typedef Union SIGVAL
{
int sival_int;
void *sival_ptr;
Attention:
(1) If the signal processing function is to be able to receive additional data, it needs to cooperate with the Sa_flags member in the sigaction structure, sa_siginfo indicates that it can accept the data.
(2) The prototype of the signal processing function is to use void myhandle_forsigaction (int signum, siginfo_t *s_t, void *p), this function is actually called by the kernel space, so the formal parameter is also in the kernel space, and Additional data received is placed in the following member of the siginfo_t structure. Si_value and Si_int are set for compatibility, with two identical content. The si_ptr corresponds to the void* pointer portion of the additional data structure body. The above two sections, when the kernel sends a signal, can only send part of it, because the extra data is a union type.
sigval_t Si_value;
int si_int; /* POSIX.1B signal
*/void * si_ptr; /* POSIX.1B Signal * *
Sample code
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> # Include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string
.h> #include <signal.h> void handler (int sig,siginfo_t *s_t,void *p)//Signal processing function signature {int TMP = 0, which can accept additional data; TMP = s_t->si_int;
Si_int and Si_value.sival_int are the same--for the extra data is int.
printf ("Aloha recv a Sig=%d\tvar:%d\n and Var is also:%d", sig,tmp,s_t->si_value.sival_int);
int main (int argc, char *argv[]) {pid_t pid;
int ret = 0;
int i = 0; The Union Sigval mysigval;//is used to hold additional data struct sigaction act;//is used to register the signal/* Use sigaction three members that must be initialized * * * act.sa_sigaction = Hand
LER;//Specifies that the callback function Act.sa_flags = sa_siginfo;//is especially important--only equal to sa_siginfo, the signal processing function can accept additional data sigemptyset (&act.sa_mask);/empty screen word
if (Sigaction (Sigint,&act,null) < 0)//Registration signal--Specifies to destroy the function {perror ("sigaction error!\n");
Exit (-1);
PID = fork ();//Create Child process if ( -1 = = pid) {perror ("fork");
Exit (-1); else if (0 = = pid) {mysigval.sival_int = 125;//set to send 10 signals to the extra data sent with the signal for (i = 0;i < 10;i++)/child process--sigint is not Signal--It's a little slow to teleport {ret = Sigqueue (Getppid (), sigint,mysigval);//Start sending signal if (Ret!= 0)/send failed {perror (
"Sigqueue");
Exit (-1);
else{//returns 0 indicating that the signal was sent successfully printf ("Send ok!\n");
Sleep (1);
}} else if (PID > 0) {while (1);//Parent Process dead Loop} return 0;
}
difference and test of reliable signal and unreliable signalReliable signals need to be cached when they encounter congestion, so there is a limit to the number of reliable signals sent, which can be viewed using the ulimit-a command. The reliable signal will arrive all the time after the unblocking, but the unreliable signal will only arrive at the last.
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> # Include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string .h> #include <signal.h>/*test_sig_limit if defined as 1 for stress testing if the definition bit 0 indicates a differential test for reliable and unreliable signals/#define TEST_SIG_LIMIT 0 # if (test_sig_limit==1) #define MAX 1024 #else #define MAX 1 #endif void handler (int sig,siginfo_t *s_t,void *p)//can accept additional data
Signature of the signal processing function {int tmp = 0;
sigset_t bset; if (sig = = SIGINT | | sig = = sigrtmin) {tmp = s_t->si_int;
Si_int and Si_value.sival_int are the same--for the extra data is int.
printf ("Aloha recv a Sig=%d\tvar:%d\t and Var is also:%d\n", sig,tmp,s_t->si_value.sival_int);
else if (sig = = SIGUSR1) {printf ("unblock\n");
* * Blocking real-time and non-real-time signals/Sigemptyset (&bset);
Sigaddset (&bset,sigint);
Sigaddset (&bset,sigrtmin);
Sigprocmask (Sig_unblock,&bset,null); else {printf ("other SiGnal\n ");
} void My_handler (int sig) {sigset_t bset;
if (sig = = SIGINT | | sig = Sigrtmin) {printf ("The sig num is:%d\n", SIG);
else if (sig = = SIGUSR1) {printf ("unblock\n");
* * Blocking real-time and non-real-time signals/Sigemptyset (&bset);
Sigaddset (&bset,sigint);
Sigaddset (&bset,sigrtmin);
Sigprocmask (Sig_unblock,&bset,null);
else {printf ("other signal\n");
int main (int argc, char *argv[]) {pid_t pid;
int ret = 0;
int i = 0;
struct Sigaction act;//is used to register the signal sigset_t bset;
Union Sigval v;
/* Use sigaction must initialize three members///act.sa_handler = my_handler;//Specify callback function act.sa_sigaction = handler; Act.sa_flags = sa_siginfo;//is especially important--only equals sa_siginfo, the signal processing function can accept additional data sigemptyset (&act.sa_mask);/empty screen word if (sigaction
(Sigint,&act,null) < 0)//Registration of Non-real-time signals {perror ("sigaction error!\n");
Exit (-1);
if (Sigaction (Sigrtmin,&act,null) < 0)//register real time signal {perror ("sigaction error!\n");
Exit (-1); } if (Sigaction (Sigusr1,&act,null) < 0)//registered user custom signal SIGUSR1 {perror ("sigaction error!\n");
Exit (-1);
}/* Blocking real-time and non-real-time signals/Sigemptyset (&bset);
Sigaddset (&bset,sigint);
Sigaddset (&bset,sigrtmin);
Sigprocmask (Sig_block,&bset,null);
PID = fork ()///Create Child process if ( -1 = = pid) {perror ("fork");
Exit (-1);
else if (0 = = pid) {v.sival_int = 0;
for (i = 1;i < max*1024;i++)/send three times unreliable signal {v.sival_int++;
ret = Sigqueue (Getppid (), sigint,v); if (ret!= 0) {printf ("Sigqueue SIGINT failed!..
Ret=%d\terrno=%d\tindex=%d\n ", ret,errno,i);/unreliable signals without caching-unlimited-no error/no execution.
Exit (-1);
} else{if (i% (1024*512) = = 0) printf ("Send SIGINT OK!--index:%d\n", i);
} v.sival_int = 0;
for (i = 1;i < max*1024;i++)//Send three times reliable signal {v.sival_int++;
ret = Sigqueue (Getppid (), sigrtmin,v); if (ret!= 0) {printf ("Sigqueue Sigrtmin failed!.. REt=%d\terrno=%d\tindex=%d\n ", ret,errno,i);//reliable signal needs caching-so there are restrictions--ulimit-a command View-At this point index is the upper bound exit (-1);
} else{if (i% = 0) printf ("Send OK!--index:%d\n", i); ret = Kill (Getppid (), SIGUSR1);//Send custom signal--unblock if (ret = 1) {printf ("Sigqueue failed!..
%d\t%d\n ", Ret,errno);
Exit (-1);
else if (ret = 0) {printf ("Send ok!\n");
} else if (PID > 0) {while (1);//Parent Process dead Loop} return 0;
}