当前位置:网站首页>Sequential state
Sequential state
2022-04-23 20:46:00 【baboon_ chen】
List of articles
One 、pause function
#include <unistd.h>
int pause(void);
/* Return value ( success ):-1, And set up errno by EINTR 1、 If the default processing action of the signal is to terminate the process , The process terminates ,pause Function has no chance to return . 2、 If the default processing action of the signal is to ignore , The process continues to be suspended ,pause Function does not return . 3、 If the signal processing action is to capture , After calling the signal processing function ,pause return -1. 4、pause The received signal cannot be shielded , If it's blocked , that pause Can't be awakened . */
Calling this function can cause the process to actively suspend , Wait for the signal to wake up . The process that calls the system call will be blocked ( Give up on your own initiative CPU) Until a signal is sent to everyone to wake it up .
Two 、 What is a sequential state ?
utilize alarm+pause Realization sleep function :
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
void catch_sigalrm(int signo)
{
}
unsigned int my_sleep(unsigned int seconds)
{
int ret;
struct sigaction act, oldact;
act.sa_handler = catch_sigalrm;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
// register SIGALRM Processing function
ret = sigaction(SIGALRM, &act, &oldact);
if (ret == -1)
{
perror("sigaction error");
exit(EXIT_FAILURE);
}
// Use alarm+pause Realization sleep function
alarm(seconds);
// ----------- There may be a loss of CPU, Lead to SIGALRM It has been sent out , But below pause Not called yet
ret = pause();
if (ret == -1 && errno == EINTR)
{
printf("pause sucess\n");
}
// If other signals are captured during waiting , Then turn off the alarm clock , Ensure the robustness of the program .
ret = alarm(0);
// recovery SIGALRM Default handler
sigaction(SIGALRM, &oldact, NULL);
// Return the waiting time of the alarm clock
return(seconds-ret);
}
int main()
{
while(1) printf("---------sleep %u seconds-------\n", my_sleep(1));
return 0;
}
In the above code, there is Time series and state The problem of . Imagine the following scenario :
Want to sleep , Set alarm clock 10 minute , hope 10 Minutes later, the alarm clock wakes itself up .
normal : timing , sleep ,10 Wake up by the alarm clock in minutes .
abnormal : When the alarm clock is set , Sleep 5 Wake up and go out to work in minutes ( Lose CPU),20 The work will be finished in minutes . Come back and go back to sleep , But the alarm clock has rung during labor (alarm Function has sent a signal ), Will not wake me up again .
3、 ... and 、 Timing problem analysis
Empathy , Review with the help of pause and alarm Realized my_sleep function . Imagine the following sequence :
- register
SIGALRM
Signal processing functions (sigaction...
)- call
alarm(1)
Function to set the alarm clock to 1 second .- The function call has just ended , Start the countdown to 1 second . Lose the current process CPU, The kernel schedules processes with high priority ( There are many. ) Replace the current process . The current process cannot get CPU, Enter the ready state and wait CPU.
- 1 Seconds later , The alarm clock timed out , The kernel sends... To the current process
SIGALRM
The signal ( Natural timing , It has nothing to do with the state of the process ), The high priority process has not finished executing , The current process is still ready , The signal cannot be processed ( outstanding ).- The high priority process has finished executing , The current process gets CPU resources , The kernel schedules the current process to execute .
SIGALRM
Signal delivery , Signal setting capture , Execute processing functions .- The execution of the signal processing function ends , Returns the current process master process ,
pause()
Called pending wait .( Want to waitalarm
Function sentSIGALRM
The signal wakes itself up )- can
SIGALRM
The signal has been processed ,pause
Don't wait for the desired signal , So we'll wait together .
Four 、 Solve the timing problem :sigsuspend function
shielding SIGALRM // So the signal can block
alarm(seconds);
// ------------------ Lose CPU
Unblock
// ------------------ It may also be lost here CPU
ret = pause(); // Actively suspend , Equal signal
You can set the mask
SIGALRM
Method to control program execution logic , But set it anyway , Programs can be inUnblock the signal
AndHang wait signal
These two operating clearances are lost CPU resources . Unless these two steps are combined into oneAtomic manipulation
.sigsuspend
Function has this function . It is used in occasions with strict timing requirementssigsuspend
Replacepause
.
#include <signal.h>
int sigsuspend(const sigset_t *mask); // Hang wait signal .
/* RETURN VALUE sigsuspend() always returns -1, with errno set to inndicate the error (normally, EINTR). */
sigsuspend During a function call , The process signal mask word is determined by its parameters mask Appoint .
A signal can be ( Such as
SIGALRM
) Shield words from temporary signalsmask
Delete in , So this is callingsigsuspend
It will remove the shielding of the signal , Then hang up and wait . Whensigsuspend
return , The signal mask word of the process is restored to its original value . If the signal is shielded ,sigsuspend
The signal is still masked after the function returns .
Improved version my_sleep
:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
void catch_sigalrm(int signo)
{
}
unsigned int my_sleep(unsigned int seconds)
{
int ret;
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspendmask;
unsigned int unslept;
// 1、 by SIGALRM Set the snap function
newact.sa_handler = catch_sigalrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
ret = sigaction(SIGALRM, &newact, &oldact);
if (ret == -1)
{
perror("sigaction error");
exit(EXIT_FAILURE);
}
// 2、 Set blocking signal set , Blocking SIGALRM The signal
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
// 3、 timing n second , Then we can produce SIGALRM The signal
alarm(seconds);
// 4、 Construct a call sigsuspend Temporarily valid blocking signal set , Release right SIGALRM The block
suspendmask = oldmask;
sigdelset(&suspendmask, SIGALRM); // Atomic manipulation
// 5、sigsuspend During call , Temporary blocking signal set is adopted suspendmask Replace the original blocking signal set
// This signal set does not contain SIGALRMM The signal , Also suspend waiting ,
// such , Even before losing CPU, The alarm clock has been sent SIGALRM The signal , The signal will be blocked .
// sigsuspend The call to... Was released SIGALRM The block , Will catch the signal , Restore program run .
sigsuspend(&suspendmask);
// Get the remaining time of the last alarm clock
unslept = alarm(0);
// 6、 recovery SIGALRM The original processing action , Echo the previous note 1
// When sigsuspend When awakened by the signal and returned , Restore the original blocking signal set .
sigaction(SIGALRM, &oldact, NULL);
// 7、 Release right SIGALRM The block , Echo the previous note 2
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return(seconds-unslept);
}
int main()
{
while(1) printf("---------sleep %u seconds-------\n", my_sleep(1));
return 0;
}
5、 ... and 、 summary
The condition of the State , It is closely related to the system load , Reflects the unreliability of the signal . The more serious the system load , The more unreliable the signal is .
Unreliability is caused by its implementation principle . The signal is realized by software ( Highly dependent on kernel scheduling , Strong delay ), After each system call , Or after interrupt processing , Need to scan PCB Pending signal set in , To determine whether to process a signal , When the system is overloaded , There will be timing confusion .
This unexpected situation can only be in the process of writing the program , Anticipate ahead of time , Actively avoid , And not through GDB Program height and other means to make up for . And because the error is irregular , Later capture and reproduction is very difficult .
版权声明
本文为[baboon_ chen]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210546350888.html
边栏推荐
- 打新债中签以后怎么办,网上开户安全吗
- Addition, deletion, modification and query of advanced MySQL data (DML)
- LeetCode 74、搜索二维矩阵
- The problem of 1 pixel border on the mobile terminal
- 100天拿下11K,转岗测试的超全学习指南
- Awk example skills
- Bracket matching -- [implementation of one-dimensional array]
- MySQL stored procedures and functions
- 居家第二十三天的午饭
- Syntaxerror: unexpected token r in JSON at position 0
猜你喜欢
go interface
Plato farm is one of the four largest online IEOS in metauniverse, and the transaction on the chain is quite high
MySQL数据库常识之储存引擎
Linux中,MySQL的常用命令
[PTA] get rid of singles
內網滲透之DOS命令
Solution: NPM err! code ELIFECYCLE npm ERR! errno 1
Matlab: psychtoolbox installation
What about laptop Caton? Teach you to reinstall the system with one click to "revive" the computer
On the three paradigms of database design
随机推荐
LeetCode 709、转换成小写字母
Leetcode 1346. Check whether integers and their multiples exist
6-5 字符串 - 2. 字符串复制(赋值) (10 分)C语言标准函数库中包括 strcpy 函数,用于字符串复制(赋值)。作为练习,我们自己编写一个功能与之相同的函数。
MySQL基础之写表(创建表)
Go limit depth traversal of files in directory
Leetcode 542, 01 matrix
C# 知识
Addition, deletion, modification and query of advanced MySQL data (DML)
I JS deep copy and shallow copy
居家第二十三天的午饭
Leetcode 1337. Row K with the weakest combat effectiveness in the matrix
Learn to C language fourth day
Learn to C language fourth day
Matlab matrix index problem
MySQL基础合集
setInterval、setTimeout、requestAnimationFrame
Another data analysis artifact: Polaris is really powerful
3-5 obtaining cookies through XSS and the use of XSS background management system
Leetcode 74. Search two-dimensional matrix
LeetCode 20、有效的括号