软中断信号及处理

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为了给用户进程也提供相应的同步、互斥以及软中断通信功能,Linux系统提供了几种相应的系统调用或库函数,其中文件锁函数lockf(fd, function, size)可用于互斥。用于同步的系统调用是wait()或sleep(n),其中wait()用于父子进程之间的同步,而sleep则使得当前进程睡眠n秒后自动唤醒自己。系统调用kill( pid, sig )和signal( sig, func )被用来传递和接收中断信号。一个进程用到的例子是signal( SIGINT, SIG_IGN ),表示当前进程忽略键盘中断信号的影响。
pause();/*使调用进程挂起,直至捕捉到一个信号*/
}else{ /*父进程*/
sleep(3);
kill(pid,SIGKILL);/*向子进程发送SIGKILL信号*/
printf("parent process send signalto kill child process!\n");
sleep(30);/*使进程睡眠30秒,期间要放弃CPU*/
ret=alarm(10);
printf("%d\n",ret);
pause();/*使调用进程挂起直至捕捉到一个信号*/
printf("I have been waken up.\n",ret);
}
程序中的使用到的两个函数的有关说明:
sleep(让进程暂停执行一段时间)
说明:设置一个时间值(闹钟时间),在将来的某个时刻该时间值会被超过。当所设置的时间值被超过后,产生SIGALRM信号。如果不忽略或不捕捉此信号,则其默认动作是终止该进程。每个进程只能有一个闹钟时间。如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,则该闹钟时间的余留值作为本次alarm函数调用的值返回。以前登记的闹钟时间则被新值代换。
Linux
1、概述
Linux的低级通信主要用来传递进程间的控制信号,主要是文件锁和软中断信号机制。软中断信号的目的是通知对方发生了异步事件。
信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
void waiting();
void stop();
void keep_alive();
int wait_mark;
2、常见信号及对信号的处理
常见的软中断信号有:
SIGHUP从终端上发出的结束信号
SIGINT来自键盘的中断信号
SIGQUIT来自键盘的退出信号
SIGFPE浮点异常信号
SIGALRM时钟定时信号
对信号的处理一般有如下三种方法:
<1>忽略该信号
<2>执行系统默认动作
<3>捕捉信号
注意信号SIGKILL和SIGSTOP既不能被捕捉,也不能被忽略。
function描述了与信号关联的动作,可以取以下三种值:
SIG_DFL:缺省操作,除SIGPWR、SIGCLD外所有信号的缺省操作是进程终结
SIG_IGN:忽视该信号的出现
Function:该进程中的一个函数地址
程序示例3:
#include<unistd.h>
#include<signal.h>
void handler()
运行结果:
因为alarm函数在定时器到点的时候产生的信号默认为让该进程退出,因此执行代码行ret=alarm(10);后10秒,进程将直接退出,终端不会输出printf中的语句。
程序示例2:父进程向子进程发送信号
#include<sys/types.h>
#include<sys/stat.h>
#include<signal.h>
Linux中有30个软中断信号和31个实时软中断信号,见图10。其中32~63是实时软中断信号,它们没有预先定义的含义,和普通软中断信号的区别在于实时信号可以排队而不会发生丢失。
软中断是对硬中断的一种模拟,发送软中断就是向接收进程的task_struct结构中的相应项发送一个信号。接收进程接收到软中断信号后,将按照事先的规定去执行一个软中断处理程序。与硬中断处理程序不一致的是,收到硬中断信号后中断处理程序立即被启动,软中断处理程序必须等到接收进程运行时才启动。另外,进程也可向自己发送软中断信号,以便在某些意外情况下,进程能转入规定好的处理程序。例如,大部分陷阱都是由当前进程自己向自己发送一个软中断信号而立即转入相应处理的。
程序示例1:该示例完成了一个简单的sleep函数的功能,由于SIGALRM默认的系统动作为终止该进程,因此在程序调用pause之后,程序就终止了。
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{int ret;
alarm(50);
#include<signal.h>
#include<sys/types.h>
int raise(int sig)
alarm()
语法格式:
#include <unistd.h>
unsigned int alarm(unsigned int seconds) ;
返回:0或以前设置的闹钟时间的余留秒数
参数:seconds的值是秒数,经过了指定的seconds秒后会产生信号SIGALRM。
{printf("hello\n");}
intmain()
{int i;
signal(SIGALRM,handler);
alarm(5);
for(i=1;i<7;i++){
printf("sleep %d ...\n",i);
sleep(1);
}
}
运行结果:
程序示例4:
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
Void msg();
int main()
{int ret;
alarm(50);
sleep(30);/*使进程睡眠30秒,期间要放弃CPU*/
ret=alarm(10);
printf("%d\n",ret百度文库;
waitpid(pid,NULL,0);/*等待pid退出*/
printf("childprocess exit!\n");
exit(0);
}
}
运行结果:
4、捕捉信号
当信号发出后,可以使用signal()方法捕获信号。
signal()函数
语法格式:
#include <signal.h>;
signal(int sig, void function());
pause(让进程暂停直到信号出现)
相关函数kill,signal,sleep
表头文件#include<unistd.h>
定义函数int pause(void);
函数说明pause()会令目前的进程暂停(进入睡眠状态),直到被信号(signal)所中断。
返回值只返回-1。
错误代码EINTR有信号到达中断了此函数。
3、发送信号
常用于发送信号的系统函数是kill、raise和alarm。
kill()函数
功能:传送信号给指定的进程
语法格式:
#include<sys/types.h>
#include<signal.h>
int kill(pid_t pid,int sig);
函数说明:
kill()可以用来送参数sig指定的信号给参数pid指定的进程。参数pid有几种情况:
相关函数signal,alarm
表头文件#include<unistd.h>
定义函数unsigned int sleep(unsigned int seconds);
函数说明sleep()会令目前的进程暂停,直到达到参数seconds所指定的时间,或是被信号所中断。
返回值若进程暂停到参数seconds所指定的时间则返回0,若有信号中断则返回剩余秒数。
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{ pid_t pid;
pid=fork();
if(pid<0) {
perror("fork() error\n");
}
if(pid==0) {/*子进程*/
printf("childprocess wait for signal!\n");
pid>0将信号传给进程识别码为pid的进程。
pid=0将信号传给和目前进程相同进程组的所有进程
pid=-1将信号广播传送给系统内所有的进程
pid<0将信号传给进程组识别码为pid绝对值的所有进程
返回值:执行成功则返回0;如果有错误则返回-1
raise()函数
功能:向正在执行的进程发送一个信号
语法格式:
信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。
信号事件的发生有两个来源:硬件来源(比如我们按下了键盘或者其它硬件故障);软件来源,最常用发送信号的系统函数是kill, raise, alarm和setitimer以及sigqueue函数,软件来源还包括一些非法运算等操作。
功能:允许调用进程控制软中断信号的处理,以非阻塞方式定义当某信号到达时如何处理。
sig指明了所要处理的信号类型,可以取除了SIGKILL和SIGSTOP外的任何一种信号,例如:
SIGHVP挂起
SIGINT键盘按ctrl+c
SIGQUIT键盘按quit键
SIGFPE浮点运算溢出
SIGKILL要求终止进程
signal(SIGALRM, msg);
pause();/*使调用进程挂起直至捕捉到一个信号*/
printf("I have been waken up.\n",ret);
}
void msg()
{printf("Catched aalarm signal!\n"); }
运行结果:
程序示例5:下面给出一个软中断信号使用的程序实现例:使用系统调用fork()创建两个子进程,再使用系统调用signal()让父进程捕捉键盘上来的中断信号(即按下Ctrl-C键);捕捉到中断信号后父进程用系统调用kill()向两个子进程发出终止信号,子进程捕捉到终止信号后输出“child process n is killed by parent!”并终止。父进程等待两个子进程终止后,输出如下信息后结束运行:“parent process is killed!”。
相关文档
最新文档