Linux programming signal (5): real-time signal and sigqueue Function

Source: Internet
Author: User

I. sigqueue Function

Function: a New System Call for sending signals. This function is mainly used for supporting signals with parameters proposed by real-time signals and works with the function sigaction.
Prototype: int sigqueue (pid_t PID, int Sig, const Union sigval value );
Parameters:
The first parameter of sigqueue is the process ID of the received signal, the second parameter is used to determine the signal to be sent, and the third parameter is a combined data structure Union sigval, which specifies the signal transmission parameter, 4-byte value.
Return Value: 0 is returned for success, and-1 is returned for failure.

Typedef Union sigval
{
Int sival_int;
Void * sival_ptr;
} Sigval_t;


Sigqueue () transmits more additional information than kill (), but sigqueue () can only send signals to one process, rather than to one process group.

Write two small programs to test:

The first is to receive the signal:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*************************************** **********************************
> File name: Process _. c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <signal. h>

# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Void handler (INT, siginfo_t *, void *);

Int main (INT argc, char * argv [])
{
Struct sigaction Act;
Act. sa_sigaction = handler; // sa_sigaction and sa_handler can only take one of them
// Sa_sigaction is mostly used for real-time signals and information can be saved
Sigemptyset (& act. sa_mask );
Act. sa_flags = sa_siginfo; // After the flag is set, other processes can be received.
// The sent data is stored in the siginfo_t struct.

If (sigaction (SIGINT, & act, null) <0)
Err_exit ("sigaction error ");

For (;;)
Pause ();

Return 0;

}

Void handler (INT Sig, siginfo_t * info, void * CTX)
{
Printf ("Recv a Sig = % d Data = % d \ n ",
Sig, info-> si_value.sival_int, info-> si_int );

}

As mentioned in the previous signal capture and sigaction functions, sa_sigaction and sa_siginfo should be used in combination. As shown above, the siginfo_t struct can also be found in this article.


Then the signal is sent:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*************************************** **********************************
> File name: Process _. c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <signal. h>

# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Int main (INT argc, char * argv [])
{
If (argc! = 2)
{
Fprintf (stderr, "usage % s PID \ n", argv [0]);
Exit (exit_failure );
}

Pid_t pid = atoi (argv [1]); // converts a string to an integer.
Union sigval val;
Val. sival_int = 100;
Sigqueue (PID, SIGINT, Val); // you can only send signals to a process, not a process group.

Return 0;

}

The test is as follows:

Run the Recv program first:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/signal $./sigqueue_recv

PS the pid of the Recv process and run the send program:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/signal $./sigqueue_send 3323

The Recv process will output a Recv statement. Of course, we can also press Ctrl + C to send signals to ourselves, as shown below, and the results are the same.

Recv a Sig = 2 Data = 100 data = 100
^ Crecv a Sig = 2 Data = 100 data = 100
^ Crecv a Sig = 2 Data = 100 data = 100

........................................ ..............

Note the two parameters of the siginfo_t struct (INT si_int;/* posix.1b signal */void
* Si_ptr;/* posix.1b signal */) values are also consistent with si_value, depending on whether sival_int or sival_ptr is sent.


Ii. Differences between real-time and unreliable Signals

The difference is explained through the program below, mainly because the real-time signal support queue will not be lost.

First, Recv program:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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>

# Define err_exit (m )\
Do \
{\
Perror (m );\
Exit (exit_failure );\
} While (0)

Void handler (INT );

Int main (INT argc, char * argv [])
{
Struct sigaction Act;
Act. sa_handler = handler;
Sigemptyset (& act. sa_mask );
Act. sa_flags = 0;

Sigset_t S;
Sigemptyset (& S );
Sigaddset (& S, SIGINT );
Sigaddset (& S, sigrtmin );
Sigprocmask (sig_block, & S, null );
If (sigaction (SIGINT, & act, null) <0)
Err_exit ("sigaction error ");

If (sigaction (sigrtmin, & act, null) <0)
Err_exit ("sigaction error ");

If (sigaction (SIGUSR1, & act, null) <0)
Err_exit ("sigaction error ");
For (;;)
Pause ();
Return 0;
}

Void handler (INT sig)
{
If (Sig = SIGINT | Sig = sigrtmin)
Printf ("Recv a Sig = % d \ n", sig );
Else if (Sig = SIGUSR1)
{
Sigset_t S;
Sigemptyset (& S );
Sigaddset (& S, SIGINT );
Sigaddset (& S, sigrtmin );
Sigprocmask (sig_unblock, & S, null );
}
}

In the main function, add the SIGINT and sigrtmin signals to the signal shielding characters. Only when the SIGUSR1 signal is received will the previous two signals be unblocked. It should be noted that, as stated in pending and blocking signals: If a signal is blocked in the signal processing function, the pending bit is cleared to 0, this signal is delivered once (the same real-time signal is generated multiple times and will arrive at the queue), but the block bit is not cleared to 0, that is, the signal is blocked again, in the pending status.


Followed by the send program:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*************************************** **********************************
> File name: sigrtime_send.c
> Author: Simba
> Mail: dameng34@163.com
> Created time: sat 23 Feb 2013 02:34:02 pm CST
**************************************** ********************************/
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <signal. h>

# Define err_exit (m )\
Do {\
Perror (m );\
Exit (exit_failure );\
} While (0)

Int main (INT argc, char * argv [])
{
If (argc! = 2)
{
Fprintf (stderr, "usage % s PID \ n", argv [0]);
Exit (exit_failure );
}

Pid_t pid = atoi (argv [1]); // converts a string to an integer.
Union sigval val;
Val. sival_int = 100;
Sigqueue (PID, SIGINT, Val); // unreliable signals are not queued, meaning they are lost.
Sigqueue (PID, SIGINT, Val );
Sigqueue (PID, SIGINT, Val );
Sigqueue (PID, sigrtmin, Val); // real-time signals are queued, meaning no loss
Sigqueue (PID, sigrtmin, Val );
Sigqueue (PID, sigrtmin, Val );
Sleep (3 );
Kill (PID, SIGUSR1 );

Return 0;

}

First run the Recv program:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/signal $./sigrtime_recv2

PS the pid of the Recv process and run the send program:

Simba @ Ubuntu :~ /Documents/code/linux_programming/apue/signal $./sigrtime_send 4076

In the send program, the SIGINT and sigrtmin signals are sent three times in a row, and then the SIGUSR1 signal is sent to the Recv process by using the kill function after 3 seconds of sleep. At this time, the Recv process outputs the following:

Recv a Sig = 34
Recv a Sig = 34
Recv a Sig = 34
Recv a Sig = 2

Real-time signals support queuing. All three signals are received, but unreliable signals do not support queuing. Only one signal is retained.


Reference: apue

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.