当前位置:网站首页>Learning about signals
Learning about signals
2022-06-30 04:25:00 【Tra220123】
One 、 The basic concept of signal
1. The user enters the command , stay shell Start a foreground process .
The user presses Ctrl-C Generate a hardware interrupt .
If CPU The process code is currently executing , The process user space code pauses execution ,CPU Switch from user mode to kernel mode to handle hardware interrupt .
The terminal driver will Ctrl-C Interpreted as SIGINT The signal , Record in this process PCB in .
At some point, before the user space code that wants to signal to return from the kernel to the process continues to execute , First deal with PCB The signal recorded in , Found a SIGINT Signal to be processed , The default processing dynamic of this signal is to terminate the process , All user space code execution that directly terminates the process without returning it .
2.kill -l Command to view the system defined signal list
Under what conditions are these signals produced , What is the default processing action , stay signal(7) Detailed description .
①Term: Terminate the current process
②Core: Terminate the current process and Core Dump
③lgn: Ignore the signal
④Stop: Stop the current process
⑤Cont: Continue the previously stopped process
3. The conditions for signal generation are ?
When the user presses some key on the terminal , The terminal driver sends a signal to the foreground process , Such as Ctrl-Z produce SIGTSTP The signal .
Signal generated by hardware abnormality , These conditions are detected by the hardware and notified to the kernel , The kernel then sends the appropriate signal to the current process .
Two 、 How to generate signals ?
1.Core Dump
When a process is about to terminate abnormally , You can choose to save all the user space memory data of the process to disk , The file name is usually core.
2. Call system functions to signal the process
kill The command is to call kill Functionally implemented .
kill Function to send a specified signal to a specified process .
raise Function to send a specified signal to the current process ( Send it to yourself ).
abort Function to make the current process receive SIGABRT Signal and abnormal termination .

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
}
if (pid) {
sleep(3);
if (kill(pid, SIGQUIT) < 0) {
perror("kill");
exit(1);
}
int sts;
wait(&sts);
if (WIFSIGNALED(sts)) {
printf("child terminate by signal %d\n", WTERMSIG(sts));
} else {
printf("child exit with other reason\n");
}
} else {
while (1) {
printf("child sleep 1 sec\n");
sleep(1);
}
}
return 0;
}#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
int pfd[2];
if (pipe(pfd) < 0) {
perror("pipe");
exit(1);
}
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
}
if (pid) {
close(pfd[0]);
close(pfd[1]);
int sts;
wait(&sts);
if (WIFSIGNALED(sts)) {
printf("signal = %d\n", WTERMSIG(sts));
} else {
printf("exit other ways\n");
}
} else {
sleep(3);
close(pfd[0]);
write(pfd[1], "hello\n", 6);
sleep(3);
}
return 0;
}3. Signals are generated by software conditions
call alarm Function to set an alarm clock ( Tell the kernel to send a message to the current process in a few seconds SIGALRM The signal )


#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
alarm(5);
alarm(3);
unsigned int left = alarm(5);
printf("left = %d\n", left);
char i;
for (i = 0; i > -1; i++) {
printf("i = %d\n", i);
}
printf("i = %d\n", i);
return 0;
}3、 ... and 、 Blocking signals
1. Signal delivery : Actually perform signal processing .
2. The signal is pending : The state of a signal from generation to delivery .
3. A process can block a signal . The blocked signal remains in the pending state when it is generated , Until the process unblocks this signal , To execute the delivery action .

Each signal has two flag bits to represent : Blocking and pending , There is also a function that executes when processing pending signal generation , The kernel sets the signal pending flag in the process control block , Until the signal reaches the sign .
4. If a signal is generated more than once before the process is unblocked , How to deal with it ?
Linux Realization : Conventional signals are generated many times before reaching, only once , Real time signals are generated many times before delivery and can be placed in a queue in turn .
Blocking signal set is also called : The signal mask word of the current process (signal mask)
5. Signal set operation function
sigset_t Type one for each signal bit Indicates a valid or invalid state , As for how this type stores these bit Depends on system implementation , From the user's point of view, there is no need to care , The user can only call the following functions to operate sigset_t Variable :

6. Signal mask word read / write function
Call function sigprocmask The signal mask word of the process can be read or changed

If the sigprocmask Unblock several current pending signals , stay sigprocmask Deliver at least one of the signals to before returning .
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int main(void) {
sigset_t set, oldset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_SETMASK, &oldset, NULL);
int n = 10;
while (n > 0) {
sleep(1);
printf("proc sleep 1s\n");
n--;
}
return 0;
}
7. Pending signal set
sigpending Read the pending signal set of the current process , adopt set Parameter out .

Call successfully returned 0, Error return -1
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void print_sig(const sigset_t *set) {
for (int i = 1; i < 32; i++) {
sigismember(set, i) ? putchar('1') : putchar('0');
}
putchar(10);
return;
}
int main(void) {
sigset_t set, oldset, pset;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGQUIT);
sigprocmask(SIG_BLOCK, &set, &oldset);
int n = 10;
while (n > 0) {
sigpending(&pset);
print_sig(&pset);
sleep(1);
n--;
}
sigprocmask(SIG_SETMASK, &oldset, NULL);
return 0;
}
Four 、 Capture the signal
1. Capture signal concept :
If the signal processing action is a user-defined function , Call this function when the signal arrives .
Because the code of the signal processing function is in the user space , The process is complicated .

2.sigaction
Read and modify the processing actions associated with the specified signal

When a signal processing function is called , The kernel automatically masks the signal currently added to the process , When the signal processing function returns, the original signal mask word is automatically restored , This ensures that when processing a signal , If this signal happens again , Then it will be blocked to the end of the current processing .
If in the signal processing function , Except that the current signal is automatically shielded , Also want to automatically shield some other signals , use sa_mask The field describes the signals of these additional collages , When the signal processing function returns, the original signal mask word is automatically restored .
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void undead(int signo) {
printf("get signo=%d, I'm alive\n", signo);
return;
}
int main(void) {
struct sigaction newact, oldact;
newact.sa_handler = undead;
newact.sa_flags = 0;
sigemptyset(&newact.sa_mask);
sigaction(SIGINT, &newact, &oldact);
int n = 20;
while (n > 0) {
sleep(1);
n--;
}
sigaction(SIGINT, &oldact, NULL);
return 0;
}
3.pause function
Suspend the calling process until a signal arrives .

If the signal processing action is to terminate the process , The process terminates ,pause Function has no chance to return .
If the signal processing action is to ignore , Then the process continues to be suspended ,pause No return .
If the signal processing action is to capture , After calling the signal processing function ,pause return -1,errno Set to EINTR: By signal terminal ,pause Only the return value in error .
4. Reentrant function
When capturing a signal , No matter where the main control flow of the process is currently executed , Will jump to the signal processing function to execute , After returning from the signal processing function, continue to execute the main control flow .
The signal processing function is a separate control flow , Because it is asynchronous with the main control flow , There is no relationship between calling and being called , And use different stack spaces .
A signal processing function is introduced to make a process have multiple control flows , If these control processes access the same global resources , There could be conflict .
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void sig_alarm(int signo) {
return;
}
unsigned int mysleep(unsigned int sec) {
struct sigaction newact, oldact;
newact.sa_handler = sig_alarm; //SIG_DFL
newact.sa_flags = 0;
sigemptyset(&newact.sa_mask);
sigaction(SIGALRM, &newact, &oldact);
alarm(sec);
pause();
int unsleep = alarm(0);
sigaction(SIGALRM, &oldact, NULL);
return unsleep;
}
int main(void) {
int n = 5;
while (n) {
printf("hello my sleep 1s\n");
mysleep(1);
n--;
}
return 0;
}5. Race condition and sigsuspend function
1. Calling pause Previous shielding SIGALRM The signal makes it impossible to reach .
2.sigsuspend contain pause The pending function of , At the same time, the problem of race condition is solved , In the case of strict timing requirements, you should call sigsuspend instead of pause.

sigsuspend No successful return value , Only after a signal processing function is executed does it return , return -1,errno Set to EINTR.
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void sig_alarm(int signo) {
return;
}
unsigned int mysleep(unsigned int sec) {
struct sigaction newact, oldact;
sigset_t newmask, oldmask, susmask;
// Replace ALARM The signal processing function of
newact.sa_handler = sig_alarm; //SIG_DFL
newact.sa_flags = 0;
sigemptyset(&newact.sa_mask);
sigaction(SIGALRM, &newact, &oldact);
// Block the alarm signal
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
// Turn on the alarm clock
alarm(sec);
// Read the old signal shielding word
susmask = oldmask;
// Delete the inside alarm The signal
sigdelset(&susmask, SIGALRM);
// Temporarily set the signal shielding word as susmask, And suspend the program to wait for the signal
sigsuspend(&susmask);
perror("sigsuspend");
int unsleep = alarm(0);
sigaction(SIGALRM, &oldact, NULL);
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return unsleep;
}
int main(void) {
alarm(2);
unsigned int unslept = mysleep(10);
printf("unslept = %d\n", unslept);
return 0;
}
6. About SIGCHLD The signal
use wait and waitpid Function to clean up zombie processes ,① The parent process can block waiting for the child process to end ,② You can also nonblocking query whether there are child processes waiting to be cleaned up ( Polling mode ).
①: If the parent process is blocked, it can't handle its own work .
②: While the parent process handles its own work, it should also remember to poll from time to time , The program implementation is complex .
When the child process terminates, it will send a message to the parent process SIGCHLD The signal , The default processing action of this signal is to ignore , The parent process can be customized SIGCHLD Signal processing function , In this way, the parent process only needs to concentrate on its own work , Don't worry about the process , Notify the parent process when the child process terminates , The parent process calls in the signal processing function. wait Just clean up the subprocess .
1. Write a program to complete the function :
The parent process fork Out of child process , Subprocess call exit(2) End , Parent process customization SIGCHLD Signal processing function , Call in it wait Get the exit status of the child process and print .
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
void sig_child(int signo) {
int sts;
wait(&sts);
if (WIFEXITED(sts)) {
printf("exit with code = %d\n", WEXITSTATUS(sts));
} else {
printf("Lemon\n");
}
return;
}
int main(void) {
pid_t pid = fork();
if (pid < 0) {
perror("fork");
exit(1);
}
if (pid) {
struct sigaction newact, oldact;
newact.sa_handler = sig_child;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGCHLD, &newact, &oldact);
int n = 10;
while (n--) {
printf("work!\n");
sleep(1);
}
} else {
sleep(3);
exit(2);
}
return 0;
}边栏推荐
- QT 6.3.1conan software package release
- FortiGate firewall modifies the default timeout of a session
- oslo_ config. cfg. ConfigFileParseError: Failed to parse /etc/glance/glance-api. Conf: a solution to errors
- Code cloud fatal: authentication failed for
- 7-3 打怪升级 单源最短路
- Input / output and interrupt technology -- microcomputer Chapter 6 learning notes
- Error in conditional filter (if) syntax in sum function in SQL Server2005
- Implementation steps of dynamic proxy
- Mongodb learning
- Knowledge - how to build rapport in sales with 3 simple skills
猜你喜欢

Myrpc version 1

Slam mapping, automatic navigation and obstacle avoidance based on ROS (bingda robot)

破局存量客群营销,试一下客户分群管理(含聚类模型等实操效果评估)

OneNote production schedule

在大厂外包呆了三年,颠覆了我的认知!

Configure specific source IP in SLA detection of FortiGate sdwan

el-upload上傳文件(手動上傳,自動上傳,上傳進度)
![Tea mall system based on SSM framework [project source code + database script + report]](/img/d9/0a46c0da9839a7186bd3a9ae55f0a5.png)
Tea mall system based on SSM framework [project source code + database script + report]

Imile uses Zadig's multi cloud environment to deploy thousands of times a week to continuously deliver global business across clouds and regions

技术分享| 融合调度中的广播功能设计
随机推荐
Unity when entering a string in the editor, escape the input of characters
Project safety and quality
What is the difference between synchronized and lock
Day 12 advanced programming techniques
Anonymous pipeline for interprocess communication
el-upload上传文件(手动上传,自动上传,上传进度)
Daily summary of code knowledge
基于SSM框架茶叶商城系统【项目源码+数据库脚本+报告】
Titanic(POJ2361)
Knowledge - how to build rapport in sales with 3 simple skills
知识点滴 - 如何用3个简单的技巧在销售中建立融洽的关系
Qt6 QML Book/Qt Quick 3D/Qt Quick 3D
2021-07-14
Named pipes for interprocess communication
Day 10 data saving and loading
errno和perror
How to use div boxes to simulate line triangles
Clients accessing the daytime service (TCP)
Errno and PERROR
FortiGate firewall quick initialization administrator password