Extends extends pthread_kill and sigaction Functions

Source: Internet
Author: User
Tags exit in

Pthread_kill:

Don't be scared by the name. pthread_kill is not a kill, but a signal sent to the thread. Do you still remember signal? Most of the default actions of signal are to terminate the running of processes. Therefore, we only need to use signal () to capture signals and add processing functions.

Int pthread_kill (pthread_t thread, int sig );

Sends a Sig signal to the thread with the specified ID. If no processing is performed in the thread code, the whole process is affected according to the default behavior of the signal. That is to say, if you send sigquit to a thread, however, if the thread does not implement the signal processing function, the entire process exits.

Pthread_kill (threadid, sigkill) is the same, killing the entire process.
If you want to obtain the correct behavior, you need to implement signal (sigkill, sig_handler) in the thread.

Therefore, if the int sig parameter is not 0, you must know what to do and implement the thread signal processing function. Otherwise, the entire process will be affected.

OK. If int SIG is 0, this is a reserved signal. It is used to determine whether the thread is still alive.

Let's take a look at the returned values of pthread_kill:
Success: 0
Thread does not exist: esrch
Invalid signal: einval

Therefore, pthread_kill (threadid, 0) is very useful.

Int kill_rc = pthread_kill (thread_id, 0 );

If (kill_rc = esrch)
Printf ("the specified thread did not exists or already quit/N ");
Else if (kill_rc = einval)
Printf ("signal is invalid/N ");
Else
Printf ("the specified thread is alive/N ");

The above code can determine whether the thread is still alive.

Sigaction:

Sigaction (int signum, const struct sigaction * Act, struct sigaction * oldact)

The sigaction function is used to check or modify the processing actions associated with the specified signal (two operations can be performed at the same time ).

It is a POSIX signal interface, while signal () is a standard C signal interface (this interface should be used if the program must run on a non-POSIX System)

Set a new signal processing function act for the signal SIGNUM, and retain the original signal processing function oldact of the signal.
Int sigaction (INT signo, const struct sigaction * restrict act,

Struct sigaction * restrict oact );

The sigaction function is used to change the SIGINT interrupt signal and Use Act. sa_handler to switch to the new operation.

The structure sigaction is defined as follows:
Struct sigaction {
Void (* sa_handler) (INT );
Sigset_t sa_mask;
Int sa_flag;
Void (* sa_sigaction) (INT, siginfo_t *, void *);
};

The sa_handler field contains the address of a Signal capture function.

The sa_mask field specifies a signal set. before calling the signal capturing function, this signal set must be added to the process's signal shielding characters. Only when the function is returned from the signal capture function, the signal shielding character of the process is reset to the original value.

Sa_flag is an option, mainly understanding two
Sa_interrupt the system calls that are interrupted by the signal will not be restarted automatically.
Sa_restart the system calls that are interrupted by the signal will be automatically restarted.

Sa_siginfo provides additional information, a pointer to the siginfo structure and a pointer to the process context identifier

The last parameter is an alternative signal processing program. It is used only when sa_siginfo is set.

Example:

# Include <stdio. h>
# Include <signal. h>
# Include <unistd. h>

Void show_handler (INT sig)
{
Printf ("I got signal % d/N", sig );
Int I;
For (I = 0; I <5; I ++ ){
Printf ("I = % d/N", I );
Sleep (1 );
}
}

Int main (void)
{
Int I = 0;
Struct sigaction act, oldact;
Act. sa_handler = show_handler;
Sigaddset (& act. sa_mask, sigquit); // See note (1)
Act. sa_flags = sa_resethand | sa_nodefer; // See note (2)
// Act. sa_flags = 0; // See note (3)

Sigaction (SIGINT, & act, & oldact );
While (1 ){
Sleep (1 );
Printf ("Sleeping % d/N", I );
I ++;
}
}

Note:
(1) If the SIGINT (CTRL + C) signal processing function show_handler is executed, the process will block the signal when it receives the sigquit (CRT +/) signal, signal sigquit will not be processed until the show_handler execution ends.
(2) sa_nodefer generally, when the signal processing function runs, the kernel will block <the given signal -- SIGINT>. However, if the sa_nodefer flag is set, the kernel will not block the signal when the signal processing function is running. Sa_nodefer is the formal POSIX name of this tag (there is also a name sa_nomask, which is generally not used for software portability)

Sa_resethand when the signal processing function is called, the signal processing function is reset to the default value. Sa_resethand is the formal POSIX name of this tag (there is also a name sa_oneshot, which is generally not used for software portability)

(3) If you do not need to reset the processing function of the given signal to the default value, and do not need to block the given signal (you do not need to set the sa_flags flag), you must reset sa_flags, otherwise, a segment error occurs. However, after sa_flags is cleared, the signal may be lost!

 

Appendix: (an example in the navigation project)

Objective: To create a function to monitor a "start" signal in real time and perform data collection periodically. It can also monitor the "stop" signal and end the collection. (The start or end signal is sent by the main program)

Implementation Method:

Create a thread in the main program.

1. Monitoring "start" signal: the thread calls pthread_cond_wait (Cond, mutex) to suspend from the beginning, and the "Start" signal of the main program can be sent through pthread_cond_signal (Cond;

2. Monitor the "stop" signal: the main program calls pthread_kill (* threadid, sig_num) to send an end signal, and then sets the processing function to capture the signal in the receiving thread.

Struct sigaction sighandler;
Sighandler. sa_handler = stopfunction;
Sigaction (sig_num, & sighandler, null );
What to do when you add and exit in the stopfunction.
After the function is executed, the thread can do anything else.
At the same time, you can receive the thread_kill signal to execute the stopfunction at any time.

Pthread_kill:

Don't be scared by the name. pthread_kill is not a kill, but a signal sent to the thread. Do you still remember signal? Most of the default actions of signal are to terminate the running of processes. Therefore, we only need to use signal () to capture signals and add processing functions.

Int pthread_kill (pthread_t thread, int sig );

Sends a Sig signal to the thread with the specified ID. If no processing is performed in the thread code, the whole process is affected according to the default behavior of the signal. That is to say, if you send sigquit to a thread, however, if the thread does not implement the signal processing function, the entire process exits.

Pthread_kill (threadid, sigkill) is the same, killing the entire process.
If you want to obtain the correct behavior, you need to implement signal (sigkill, sig_handler) in the thread.

Therefore, if the int sig parameter is not 0, you must know what to do and implement the thread signal processing function. Otherwise, the entire process will be affected.

OK. If int SIG is 0, this is a reserved signal. It is used to determine whether the thread is still alive.

Let's take a look at the returned values of pthread_kill:
Success: 0
Thread does not exist: esrch
Invalid signal: einval

Therefore, pthread_kill (threadid, 0) is very useful.

Int kill_rc = pthread_kill (thread_id, 0 );

If (kill_rc = esrch)
Printf ("the specified thread did not exists or already quit/N ");
Else if (kill_rc = einval)
Printf ("signal is invalid/N ");
Else
Printf ("the specified thread is alive/N ");

The above code can determine whether the thread is still alive.

Sigaction:

Sigaction (int signum, const struct sigaction * Act, struct sigaction * oldact)

The sigaction function is used to check or modify the processing actions associated with the specified signal (two operations can be performed at the same time ).

It is a POSIX signal interface, while signal () is a standard C signal interface (this interface should be used if the program must run on a non-POSIX System)

Set a new signal processing function act for the signal SIGNUM, and retain the original signal processing function oldact of the signal.
Int sigaction (INT signo, const struct sigaction * restrict act,

Struct sigaction * restrict oact );

The sigaction function is used to change the SIGINT interrupt signal and Use Act. sa_handler to switch to the new operation.

The structure sigaction is defined as follows:
Struct sigaction {
Void (* sa_handler) (INT );
Sigset_t sa_mask;
Int sa_flag;
Void (* sa_sigaction) (INT, siginfo_t *, void *);
};

The sa_handler field contains the address of a Signal capture function.

The sa_mask field specifies a signal set. before calling the signal capturing function, this signal set must be added to the process's signal shielding characters. Only when the function is returned from the signal capture function, the signal shielding character of the process is reset to the original value.

Sa_flag is an option, mainly understanding two
Sa_interrupt the system calls that are interrupted by the signal will not be restarted automatically.
Sa_restart the system calls that are interrupted by the signal will be automatically restarted.

Sa_siginfo provides additional information, a pointer to the siginfo structure and a pointer to the process context identifier

The last parameter is an alternative signal processing program. It is used only when sa_siginfo is set.

Example:

# Include <stdio. h>
# Include <signal. h>
# Include <unistd. h>

Void show_handler (INT sig)
{
Printf ("I got signal % d/N", sig );
Int I;
For (I = 0; I <5; I ++ ){
Printf ("I = % d/N", I );
Sleep (1 );
}
}

Int main (void)
{
Int I = 0;
Struct sigaction act, oldact;
Act. sa_handler = show_handler;
Sigaddset (& act. sa_mask, sigquit); // See note (1)
Act. sa_flags = sa_resethand | sa_nodefer; // See note (2)
// Act. sa_flags = 0; // See note (3)

Sigaction (SIGINT, & act, & oldact );
While (1 ){
Sleep (1 );
Printf ("Sleeping % d/N", I );
I ++;
}
}

Note:
(1) If the SIGINT (CTRL + C) signal processing function show_handler is executed, the process will block the signal when it receives the sigquit (CRT +/) signal, signal sigquit will not be processed until the show_handler execution ends.
(2) sa_nodefer generally, when the signal processing function runs, the kernel will block <the given signal -- SIGINT>. However, if the sa_nodefer flag is set, the kernel will not block the signal when the signal processing function is running. Sa_nodefer is the formal POSIX name of this tag (there is also a name sa_nomask, which is generally not used for software portability)

Sa_resethand when the signal processing function is called, the signal processing function is reset to the default value. Sa_resethand is the formal POSIX name of this tag (there is also a name sa_oneshot, which is generally not used for software portability)

(3) If you do not need to reset the processing function of the given signal to the default value, and do not need to block the given signal (you do not need to set the sa_flags flag), you must reset sa_flags, otherwise, a segment error occurs. However, after sa_flags is cleared, the signal may be lost!

 

Appendix: (an example in the navigation project)

Objective: To create a function to monitor a "start" signal in real time and perform data collection periodically. It can also monitor the "stop" signal and end the collection. (The start or end signal is sent by the main program)

Implementation Method:

Create a thread in the main program.

1. Monitoring "start" signal: the thread calls pthread_cond_wait (Cond, mutex) to suspend from the beginning, and the "Start" signal of the main program can be sent through pthread_cond_signal (Cond;

2. Monitor the "stop" signal: the main program calls pthread_kill (* threadid, sig_num) to send an end signal, and then sets the processing function to capture the signal in the receiving thread.

Struct sigaction sighandler;
Sighandler. sa_handler = stopfunction;
Sigaction (sig_num, & sighandler, null );
What to do when you add and exit in the stopfunction.
After the function is executed, the thread can do anything else.
At the same time, you can receive the thread_kill signal to execute the stopfunction at any time.

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.