三十三、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 译者:李秋豪 信号与进程几乎控制了操作系统的每个任务. 在 ...
随机推荐
- SNMP扫描
------------------------------------------------------------------grub引导密码:[root@localhost ~]# jm4pt ...
- luogu5019 [NOIp2018]铺设道路 (贪心)
和NOIp2013 积木大赛一模一样 我在堆一格的时候,我把它尽量地往右去延伸 于是如果对于一个i,a[i-1]<a[i],那i在之前一定只堆过a[i-1]那么多,所以要再堆a[i]-a[i-1 ...
- 天梯赛 L2-001 紧急救援
L2-001 紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道 ...
- BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)
题面: bzoj题面有误,还是看luogu的吧 https://www.luogu.org/problemnew/show/P1892 题解: 种类并查集.. 因为有敌人的敌人是朋友这个条件,所以需要 ...
- 每个Java程序员需要了解的8个Java开发工具
每个Java程序员需要了解的8个Java开发工具 Java是计算机应用程序编程语言,被广泛用于创建Web应用.服务器处理.用户端的API开发乃至数据库等多个领域.下面列出了8个有助于你开发Java应用 ...
- A1009. Product of Polynomials
This time, you are supposed to find A*B where A and B are two polynomials. Input Specification: Each ...
- 【CF1154】题解
A 直接模拟即可. B 对数组中的值进行排序去重.发现若去重之后的数组中有大于 3 个数时无解,因为无法找到一个点到数轴上四个点的距离均相等.若去重之后的数组中只有三个值,则判断中间的值是否到两边的值 ...
- python面向对象编程 -- 封装、继承
面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...
- C++ const 理解
转载自:https://www.cnblogs.com/jiabei521/p/3335676.html 如果函数需要传入一个指针,面试官可能会问是否需要为该指针加上const,把const加在指针不 ...
- Educational Codeforces Round 55 (Rated for Div. 2) B. Vova and Trophies
传送门 https://www.cnblogs.com/violet-acmer/p/10035971.html 题意: Vova有n个奖杯,这n个奖杯全部是金奖或银奖,Vova将所有奖杯排成一排,你 ...