Introduction to Linux programming-Signal Processing

Source: Internet
Author: User
Tags sigint signal
Introduction to Linux programming-Signal Processing-general Linux technology-Linux programming and kernel information. For more information, see the following. Linux signal events
In this chapter, we will discuss the signal processing functions in Linux.
Signal processing functions in Linux:
Signal Generation
Signal Processing
Other Signal Functions
One instance
1. Signal Generation
The signal in Linux is similar to the INT in DOS or Windows. When a signal occurs
The signal we believe will be sent to the corresponding process. In Linux, the signal is as follows. We use kill-l
Command to get the following output results:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR
For a detailed explanation of these signals, see the output result of man 7 signal. There are two sources for the occurrence of signal events.
One is the hardware (for example, when we press the keyboard), the other is the software (for example, we use system functions or
). The four most commonly used system functions are kill, raise, alarm, and setit.
The timer function. setitimer function we will learn again in the chapter on timer usage.
# I nclude
# I nclude
# I nclude
Int kill (pid_t pid, int sig );
Int raise (int sig );
Unisigned int alarm (unsigned int seconds );
The kill system call sends signal sig to the process.
If the pid is positive, the signal sig is sent to the process pid.
If the pid is equal to 0, the signal sig is sent to the process in the same process group as the pid process.
If the pid is equal to-1, the signal is sent to all processes in the progress table, except the process number at the maximum.
If the pid is-1, it is the same as 0, but the sending process group is-pid.
The first case is the most used. Do you still remember the example in the daemon section? At that time, we used this
The functions killed the creation of the parent process daemon.
The raise system call sends a sig signal to itself. We can use the above function to implement this function.
The alarm function has a relationship with time. This function can send a SIGALRM signal to itself after seconds.
... What will happen to this function?
# I nclude
Main ()
{
Unsigned int I;
Alarm (1 );
For (I = 0; 1; I ++)
Printf ("I = % d", I );
}
The default operation of SIGALRM is to terminate the process, so the program will end in 1 second. You can see what your last I value is.
, To compare the differences in system performance (my number is 2232 ).
2. Signal operations sometimes we want the process to be correctly executed, rather than being affected by the signal, such
We hope that the above program will not end in one second. At this time, we will perform signal operations.
Signal shielding is the most common method for signal operations. The following functions are used for signal shielding.
# I nclude
Int sigemptyset (sigset_t * set );
Int sigfillset (sigset_t * set );
Int sigaddset (sigset_t * set, int signo );
Int sigdelset (sigset_t * set, int signo );
Int sigismember (sigset_t * set, int signo );
Int sigprocmask (int how, const sigset_t * set, sigset_t * oset );
The sigemptyset function initializes the signal set and sets it to null. sigfillset also initializes the signal set, only
Set the signal set to the set of all signals. sigaddset adds the signal signo to the set of signals, sigd
Elset deletes the signal from the signal set. sigismember queries whether the signal is in the signal set.
Sigprocmask is the most critical function. Before using sigprocmask, set the signal set.
It is used to add the specified signal set to the signal blocking set of the process. If oset is provided, the current
The process signal blocking set will be saved in the oset. The parameter how determines the function operation method.
SIG_BLOCK: adds a signal set to the blocking set of the current process.
SIG_UNBLOCK: deletes a signal set from the current blocking set.
SIG_SETMASK: sets the current signal set as a signal blocking set.
Use these functions as an example.
# I nclude
# I nclude
# I nclude
# I nclude
Int main (int argc, char ** argv)
{
Double y;
Sigset_t intmask;
Int I, repeat_factor;
If (argc! = 2)
{
Fprintf (stderr, "Usage: % s repeat_factor \ n \ a", argv [0]);
Exit (1 );
}
If (repeat_factor = atoi (argv [1]) <1) repeat_factor = 10;
Sigemptyset (& intmask);/* set the signal set to null */
Sigaddset (& intmask, SIGINT);/* Add the Ctrl + C signal to interrupt */
While (1)
{
/* Blocking signal. We do not want to save the original set. Therefore, the parameter is NULL */
Sigprocmask (SIG_BLOCK, & intmask, NULL );
Fprintf (stderr, "SIGINT signal blocked \ n ");
For (I = 0; I Fprintf (stderr, "Blocked calculation is finished \ n ");
/* Cancel blocking */
Sigprocmask (SIG_UNBLOCK, & intmask, NULL );
Fprintf (stderr, "SIGINT signal unblocked \ n ");
For (I = 0; I Fprintf (stderr, "Unblocked calculation is finished \ n ");
}
Exit (0 );
}
When the program is running, we need to use Ctrl + C to end. If we send a SIGINT signal during the first calculation
Because the signal has been blocked, the program does not reflect it. The program will end only when the signal is canceled and blocked.
Note that we only need to send a SIGINT signal once, because the signal shielding only adds the signal to the signal blocking.
The signal is not discarded in the set. Once the signal shielding is canceled, this signal will take effect.
Sometimes we want to reflect the signal in a timely manner. For example, when we press Ctrl + C, we don't want to do anything.
We want to tell you that this operation is not good. Please do not try again, instead of reflecting it.
We need to use the sigaction function.
# I nclude

Int sigaction (int signo, const struct sigaction * act,
Struct sigaction * oact );
Struct sigaction {
Void (* sa_handler) (int signo );
Void (* sa_sigaction) (int siginfo_t * info, void * act );
Sigset_t sa_mask;
Int sa_flags;
Void (* sa_restore) (void );
}
Isn't this function and structure a little scary? Don't be scared. In fact, this function is used quite
Simple. Let's first explain the meaning of each parameter. signo is simply the signal we want to process. It can be
Any valid signal. Two signals cannot be used (SIGKILL and SIGSTOP). act contains
Information on how to process the signal. oact is simpler than the previous processing information for this function, which is mainly used to ensure
Store information. Generally, NULL is OK.
The signal structure is a little complicated. It doesn't matter how we learn it.
Sa_handler is a function pointer pointing to a function, which has a parameter.
Is the signal operation function we want to perform. sa_sigaction, sa_restore and sa_handler are similar, only
The parameters are different. These two elements are rarely used, so they don't matter.
Sa_flags is used to set various signal operations. It is generally set to 0. We have learned sa_mask.
We can use sa_handler to point to one of our signal operation functions. sa_handler has
Two special values: SIG_DEL and SIG_IGN.SIG_DEL use the default signal operation function, while SIG_IGN uses
The operation function that ignores this signal.
This function is complex. We use an example to describe it. The following function can capture the user's CTRL + C signal and Input
Generates a prompt statement.
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
# Define PROMPT "do you want to terminate the program? "
Char * prompt = PROMPT;
Void ctrl_c_op (int signo)
{
Write (STDERR_FILENO, prompt, strlen (prompt ));
}
Int main ()
{
Struct sigaction act;
Act. sa_handler = ctrl_c_op;
Sigemptyset (& act. sa_mask );
Act. sa_flags = 0;
If (sigaction (SIGINT, & act, NULL) <0)
{
Fprintf (stderr, "Install Signal Action Error: % s \ n \ a", strerror (errno ));
Exit (1 );
}
While (1 );
}
In the signal operation function of the above program, we use the write function instead of the fprintf function.
We need to consider the following situation. If we have another signal during signal operation, then the program should
How to run it? To process the signal when the signal processing function is running, we need to set sa_mask
Clerk. we add the signal we want to shield to the sa_mask structure, so that these functions are used during signal processing.
Will be blocked.
3. Other signal functions are complex in signal operation and processing. We will introduce several signal operation functions.

# I nclude
# I nclude
Int pause (void );
Int sigsuspend (const sigset_t * sigmask );
The pause function is very simple, that is, to suspend a process until a signal occurs. While sigsuspend is also to suspend a process only in
Use sigmask to replace the current signal blocking set during the call.
# I nclude
Int sigsetjmp (sigjmp_buf env, int val );
Void siglongjmp (sigjmp_buf env, int val );
Do you still remember the goto function or setjmp and longjmp functions? These two signal jump functions can also implement the Program
Jump allows us to jump from the function to what we need.
Since the above functions are rarely met, we just explained them. For details, please refer to the online help.
4. Do you still remember which program we created in the daemon for an instance? Here, the daemon
Enhance the program. The program below will also check the user's email. However, a switch is provided.
If the user does not want the program to prompt for a new email, he can send the SIGUSR2 signal to the program.
Send the SIGUSR1 signal.
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
# I nclude
/* The personal email address of Linux users is/var/spool/mail /*/
# Define MAIL_DIR "/var/spool/mail /"
/* Sleep for 10 seconds */
# Define SLEEP_TIME 10
# Define MAX_FILENAME 255
Unsigned char policyflag = 1;
Long get_file_size (const char * filename)
{
Struct stat buf;
If (stat (filename, &; buf) =-1)
{
If (errno = ENOENT) return 0;
Else return-1;
}
Return (long) buf. st_size;
}
Void send_mail_notify (void)
{
Fprintf (stderr, "New mail has arrived7 \ n ");
}
Void turn_on_notify (int signo)
{
Notifyflag = 1;
}
Void turn_off_notify (int signo)
{
Notifyflag = 0;
}
Int check_mail (const char * filename)
{
Long old_mail_size, new_mail_size;
Sigset_t blockset, emptyset;
Sigemptyset (&; blockset );
Sigemptyset (&; emptyset );
Sigaddset (&; blockset, SIGUSR1 );
Sigaddset (&; blockset, SIGUSR2 );
Old_mail_size = get_file_size (filename );
If (old_mail_size <0) return 1;
If (old_mail_size> 0) send_mail_y y ();
Sleep (SLEEP_TIME );
While (1)
{
If (sigprocmask (SIG_BLOCK, &; blockset, NULL) <0) return 1;
While (policyflag = 0) sigsuspend (&; emptyset );
If (sigprocmask (SIG_SETMASK, &; emptyset, NULL) <0) return 1;
New_mail_size = get_file_size (filename );
If (new_mail_size> old_mail_size) send_mail_notify;
Old_mail_size = new_mail_size;
Sleep (SLEEP_TIME );
}
}
Int main (void)
{
Char mailfile [MAX_FILENAME];
Struct sigaction newact;
Struct passwd * pw;
If (pw = getpwuid (getuid () = NULL)
{
Fprintf (stderr, "Get Login Name Error: % s \ n \ a", strerror (errno ));
Exit (1 );
}
Strcpy (mailfile, MAIL_DIR );
Strcat (mailfile, pw-> pw_name );
Newact. sa_handler = turn_on_policy;
Newact. sa_flags = 0;
Sigemptyset (&; newact. sa_mask );
Sigaddset (&; newact. sa_mask, SIGUSR1 );
Sigaddset (&; newact. sa_mask, SIGUSR2 );
If (sigaction (SIGUSR1, &; newact, NULL) <0)
Fprintf (stderr, "Turn On Error: % s \ n \ a", strerror (errno ));
Newact. sa_handler = turn_off_policy;
If (sigaction (SIGUSR1, &; newact, NULL) <0)
Fprintf (stderr, "Turn Off Error: % s \ n \ a", strerror (errno ));
Check_mail (mailfile );
Exit (0 );
}
Signal operations are a very complex task, more complex than we think. If you want to completely
Find out the problems of signal operations, and read the online manual in addition to a large number of exercises. However, if we
In general use, the above functions are similar. We will introduce them here.
Related Article

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.