三十三、Linux 进程与信号——中断系统调用和函数可重入性
33.1 中断系统调用
- 进程调用 “慢” 系统调用时,如果发生了信号,内核会重启系统调用。
- 慢系统调用
- 可能会永久阻塞的系统调用
- 从终端设备、管道或网络设备上的文件读取
- 向上述文件写入
- 某些设备上的文件打开
- pause 和 wait 系统调用
- 一些设备的 ioctl 操作
- 一些进程间通信函数
33.1.1 慢系统调用引起的调用重启
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h> void sig_handler(int signo)
{
if(signo == SIGTSTP){
printf("SIGTSTP occured\n");
}
} int main(void)
{
char buffer[];
ssize_t size; if(signal(SIGTSTP, sig_handler) == SIG_ERR){
perror("signal sigtstp error");
} printf("begin running and waiting for signal\n");
size = read(STDIN_FILENO, buffer, );
if(size < ){
perror("read error");
} printf("reading finished\n"); if(write(STDOUT_FILENO, buffer, size) != size) {
perror("write error");
}
printf("end running\n");
return ;
}
33.1.2 自定义函数
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h> void sig_handler(int signo)
{
if(signo == SIGTSTP){
printf("SIGTSTP occured\n");
}
} void call_fun(void)
{
printf("begin running call_fun\n");
sleep();
printf("end running call_fun\n");
} int main()
{
if(signal(SIGTSTP, sig_handler) == SIG_ERR){
perror("signal sigtstp error");
} printf("begin running main\n");
call_fun();
printf("end running main\n");
}
33.2 函数可重入性
- 在调用某个函数过程中出现信号,且该信号处理函数中再次调用该函数
- 访问全局或静态变量的函数是不可重入函数
- 即前后数据不一致
- 若是函数内部的局部变量,则此函数是可重入函数
- 即前后数据一致
- 访问全局或静态变量的函数是不可重入函数
- 程序片段如下:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> int g_v[];
int *h_v; ///< 堆中变量 void set(int val)
{
int a_v[]; int i = ;
for(; i < ; i++) {
a_v[i] = val;
g_v[i] = val;
h_v[i] = val;
sleep();
} printf("g_v:");
for(i = ; i < ; i++){
if(i != ) {
printf(", %d", g_v[i]);
}
else {
printf(", %d", g_v[i]);
}
}
printf("\n"); printf("h_v:");
for(i = ; i < ; i++){
if(i != ) {
printf(", %d", h_v[i]);
}
else {
printf(", %d", h_v[i]);
}
} printf("\n");
printf("a_v:");
for(i = ; i < ; i++){
if(i != ) {
printf(", %d", a_v[i]);
}
else {
printf(", %d", a_v[i]);
}
}
} void sig_handler(int signo)
{
if(signo == SIGTSTP){
printf("SIGTSTP occured\n");
set();
printf("\nend SIGTSTP\n");
}
}
int main(void)
{
if(signal(SIGTSTP, sig_handler) == SIG_ERR){
perror("signal sigtstp error");
} h_v = (int *)calloc(, sizeof(int)); printf("begin running main\n");
set();
printf("\nend running main\n");
return ;
}
运行结果:
全局变量中的数据不可控,局部变量都为 10
第一次调用 set 函数的时候,set(10) 中的循环运行了 2 次,此时 i = 2,然后中断,再次运行set(20) 函数,此时将所有变量中的值覆盖掉了,中断完了之后,函数继续从中断的地方运行,此时中断的地方 i = 2,则全局变量和堆变量从此处开始运行,后面的 20 都被 10 给覆盖。
三十三、Linux 进程与信号——中断系统调用和函数可重入性的更多相关文章
- 三十四、Linux 进程与信号——信号特点、信号集和信号屏蔽函数
34.1 信号特点 信号的发生是随机的,但信号在何种条件下发生是可预测的 进程杠开始启动时,所有信号的处理方式要么默认,要么忽略:忽略是 SIGUSR1 和 SIGUSR2 两个信号,其他都采取默认方 ...
- 函数可重入问题reentrant functions(函数执行过程中可以被中断,允许多个副本)
最近经常听到这个名词,以前也听到过,不过接触更多的是“线程安全问题”,而且本人也一直理解的是两个名字的含义是一样的.今天仔细总结一下这个名词相关的概念. 引用博文:可重入函数和不可重入函数 (http ...
- 三十、Linux 进程与信号——信号的概念及 signal 函数
30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...
- 二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程
23.1 进程链和进程扇 23.1.1 概念 进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程.... 这种就为进程链 进程扇:一个父进程构建出多个子进程,子进程都 ...
- 三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数
31.1 SIGCHLD 信号 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用 wait 调用来等待子进程结束并回收它. 避免僵尸进程 #include <stdio.h> # ...
- 第9章 Linux进程和信号超详细分析
9.1 进程简单说明 进程是一个非常复杂的概念,涉及的内容也非常非常多.在这一小节所列出内容,已经是我极度简化后的内容了,应该尽可能都理解下来,我觉得这些理论比如何使用命令来查看状态更重要,而且不明白 ...
- 十八、Linux 进程与信号---进程介绍
18.1 进程的概念 程序:程序(program)是存放再磁盘文件中的可执行文件 进程 程序的执行实例被称为进程(process) 一个程序的执行实例可能由多个 进程具有独立的权限和职责.如果系统中某 ...
- Linux 进程与信号的概念和操作
进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 信号与进程几乎控制了操作系统的每个任务. 在shell中输 ...
- Linux 进程与信号的概念和操作 linux process and signals
进程 主要参考: http://www.bogotobogo.com/Linux/linux_process_and_signals.php 译者:李秋豪 信号与进程几乎控制了操作系统的每个任务. 在 ...
随机推荐
- [SCOI2016]萌萌哒(倍增+并查集)
一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1 ...
- angular2的lazyload初体验
angular2自带了lazyload,就是路由的loadChild,要优化ng2项目必不可少.代码已更新到ng-demo ->https://github.com/chenby/ng2-dem ...
- Ubuntu中VisualBox无法识别USB设备
解决方法 安装Oracle VM VirtualBox Extension Pack( https://www.virtualbox.org/wiki/Downloads ) 执行sudo /usr/ ...
- Linux:去除每一行行首的空格
如下命令: sed 's/^ *//' file1.txt > file2.txt
- 第一节,初识OpenCV3-图像的读、写、显、格式转化等
之前一直在看深度学习,突然用到了对图像处理的东西,所以过来补充一下OpenCV基础. 就顺便从网上了买了一本OpenCV 3计算机视觉这本书,这本书比较薄,但是目前已经够我用了,在这里就记录一下我的学 ...
- windows怎样查看被程序占用的端口
1. netstat -ano 显示所有端口与任务管理器中的pid对应,通过pid打开任务管理器查询占用进程 附录:在命令行中输入netstat /? 可以查看netstat的相关信息.C:\Doc ...
- mysql优化好文
https://segmentfault.com/a/1190000006158186
- Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机
题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...
- Altium Designer 18 ------ 常用功能记录
PCB选中某条线路,按一下 Tab 键选中整条线路 PCB中,按 “N” 键选择隐藏或显示某个网络 配置Altium Designer 18 教程所需的捕捉网格的值: G显示Snap Grid菜单,您 ...
- 微信小程序:图片预览
wxml页面: <image src='{{UPLOAD_IMAGES_URL}}{{vv.img_s}}' data-src="{{vv.img}}" bindtap=&q ...