20191227甘泞与第六章学习笔记

技术20191227甘泞与第六章学习笔记 20191227甘泞与第六章学习笔记第6章 信号和信号处理
6.1信号和中断
信号:发给进程的请求,将进程从正常执行转移到中断处理。
中断:是从I/O设备或协处

20191227甘宁第六章学习笔记

第6章 信号和信号处理

6.1信号和中断

信号:发送给进程的请求,将进程从正常执行转移到中断处理。

中断:从输入输出设备或协处理器发送到中央处理器的外部请求,将中央处理器从正常执行转移到中断处理。

“中断”是发送给进程的事件,它将进程从正常活动转移到其他活动,称为“中断处理”。“进程”在完成“中断”处理后可以恢复正常活动。

有以下类型的终端:

1.人员中断

2.过程中断

3.硬件中断

4.进程的陷阱错误

Unix/Linux的信号处理

(1)按Ctrl C通常会导致当前正在运行的进程终止。原因如下:Ctrl C组合键会产生键盘硬件中断。键盘中断处理程序将Ctrl C组合键转换为SIGINT(2)信号,发送给终端上的所有进程,唤醒等待键盘输入的进程。在内核模式下,每个进程都必须检查和处理未完成的信号。对于大多数信号,进程的默认操作是调用内核的kexit(exitValue)函数来终止。在Linux中,exitValue的低位字节是导致进程终止的信号号。

(2)用户可以使用命令nohup a.out在后台运行程序。即使在用户退出后,该进程也将继续运行。

(3)用户再次登录时可能会发现(通过ps-u LTD)后台进程仍在运行。用户可以使用sh命令kill pid(或kill -s 9 pid)来终止进程。

信号处理函数

每个处理模块都有一个信号处理阵列intsig [32]。sig[32]数组的每个条目指定如何处理相应的信号,其中0表示DEFault,1表示IGNore。下图显示了信号位向量、屏蔽位向量和信号处理功能。

如果信号位向量中的位I为1,将生成信号I或将其发送给进程。如果屏蔽位向量的位1为1,信号将被阻塞或屏蔽。否则,信号不会被阻断。只有当信号存在且未被阻塞时,信号才会生效或被传递给进程。

信号的发送

发送信号的主要功能有kill()、raise()、sigqueue()、alarm()、setitimer()和abort()。1、kill()

#包含系统/类型. h

#包含信号. h

int kill(pid_t pid,int signo)

参数pid值信号的接收过程

0 pid进程id为pid进程。

Pid=0同一进程组的进程

pid0 pid!=-1进程组标识为-pid的所有进程

Pid=-1进程标识大于1的所有进程,发送进程本身除外

Sinno是信号值。当它为0(即零信号)时,它实际上不发送任何信号,但照常进行错误检查。因此,它可以用来检查目标进程是否存在,以及当前进程是否有向目标发送信号的权限(具有root权限的进程可以向任何进程发送信号,而没有root权限的进程只能向属于同一会话或同一用户的进程发送信号)。

Kill()最常用于pid0被调用时的信令,调用成功返回0;否则,返回-1。注意:在pid0的情况下,不同的版本对于哪些进程会接收信号有不同的看法,其实很简单。只需参考内核源代码/signal.c .上表中的规则参考红帽7.2。

2、raise()

#包含信号. h

int raise(int signo)

向进程本身发送信号,参数是要发送的信号值。呼叫成功返回0;否则,返回-1。

3、sigqueue()

#包含系统/类型. h

#包含信号. h

int sigqueue(pid_t pid,int sig,const union sigval)

呼叫成功返回0;否则,返回-1。

Sigqueue()是一个比较新的信令系统调用,主要是针对实时信号提出的(当然也支持前32种)。支持信号有参数,与函数sigaction()一起使用。

sigqueue的第一个参数指定了接收信号的进程ID,第二个参数决定了要发送的信号,第三个参数是联合数据结构union sigval,它指定了信号传输的参数,也就是俗称的4字节值。

typedef union sigval { int sival _ int;void * sival _ ptr} sigval _ t;

Sigqueue()提供的附加信息比kill()多,但是sigqueue()只能向一个进程发送信号,而不能向一个进程组发送信号。如果signo=0,它将被执行。

错误检查,但实际上不发送任何信号,0值信号可用于检查pid的有效性以及当前进程是否有权限向目标进程发送信号。

在调用sigqueue时,sigval_t指定的信息会拷贝到3参数信号处理函数(3参数信号处理函数指的是信号处理函数由sigaction安装,并设定了sa_sigaction指针,稍后将阐述)的siginfo_t结构中,这样信号处理函数就可以处理这些信息了。由于sigqueue系统调用支持发送带参数信号,所以比kill()系统调用的功能要灵活和强大得多。

注:sigqueue()发送非实时信号时,第三个参数包含的信息仍然能够传递给信号处理函数; sigqueue()发送非实时信号时,仍然不支持排队,即在信号处理函数执行过程中到来的所有相同信号,都被合并为一个信号。

4、alarm()

#include unistd.h 
unsigned int alarm(unsigned int seconds) 

专门为SIGALRM信号而设,在指定的时间seconds秒后,将向进程本身发送SIGALRM信号,又称为闹钟时间。进程调用alarm后,任何以前的alarm()调用都将无效。如果参数seconds为零,那么进程内将不再包含任何闹钟时间。
返回值,如果调用alarm()前,进程中已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。

5、setitimer()

#include sys/time.h 
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)); 

setitimer()比alarm功能强大,支持3种类型的定时器:

ITIMER_REAL: 设定绝对时间;经过指定的时间后,内核将发送SIGALRM信号给本进程;
ITIMER_VIRTUAL 设定程序执行时间;经过指定的时间后,内核将发送SIGVTALRM信号给本进程;
ITIMER_PROF 设定进程执行以及内核因本进程而消耗的时间和,经过指定的时间后,内核将发送ITIMER_VIRTUAL信号给本进程;
Setitimer()第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例,结构itimerval形式见附录1。第三个参数可不做处理。

Setitimer()调用成功返回0,否则返回-1。

6、abort()

#include stdlib.h 
void abort(void);

向进程发送SIGABORT信号,默认情况下进程会异常退出,当然可定义自己的信号处理函数。即使SIGABORT被进程设置为阻塞信号,调用abort()后,SIGABORT仍然能被进程接收。该函数无返回值。

信号捕捉函数

进程可使用系统调用:int r =signal(int signal_numberr void *handler);来修改选定信号编号的处理函数,SIGKILL(19)除外,它们不能修改。signal()系统调用在所有类Unix系统中均可用,但它有一些缺点:

  • 在执行已安装的信号捕捉函数之前,通常将信号处理函数重置为DEFault。为捕捉下一次出现相同的信号,必须重新安装捕捉函数。
  • signal()不能阻塞其他信号
  • 不同Unix版本的signal。可能会有所不通不同。
    所以现在signal()已经被sigaciton()所代替,它的原型是int sigaction (int signum, const struct sigaction *act, struct sigaction *oldact);,sigaction结构体的定义为

其中重要的字段如下:

sa_handler :该字段是指向处理函数的指针,该函数与signal()的处理函数有相同的原型。
sa_sigaction:该字段是运行信号处理函数的另一种方法。它的信号编号旁边有两个额外参数,其中siginfo t *提供关于所接收信号的更多信息。
sa_mask:可在处理函数执行期间设置要阻塞的信号。
sa_flags :可修改信号处理进程的行为。若要使用sa_sigaction处理函数,必须将sa_flags设置为SA_SIGINFO。

实践内容

/* sigset.c */
    #include sys/types.h
    #include unistd.h
    #include signal.h
    #include stdio.h
    #include stdlib.h
    /* 自定义的信号处理函数 */
    void my_func(int signum)
    {
        printf("If you want to quit,please try SIGQUIT\n");
    }
    int main()
    {
        sigset_t set,pendset;
        struct sigaction action1,action2;
        /* 初始化信号集为空 */
        if (sigemptyset(set)  0)
        {
            perror("sigemptyset");
            exit(1);
        }
        /* 将相应的信号加入信号集 */
        if (sigaddset(set, SIGQUIT)  0)
        {
            perror("sigaddset");
            exit(1);
        }
        if (sigaddset(set, SIGINT)  0)
        {
            perror("sigaddset");
            exit(1);
        }
        if (sigismember(set, SIGINT))
        {
            sigemptyset(action1.sa_mask);
            action1.sa_handler = my_func;
            action1.sa_flags = 0;
            sigaction(SIGINT, action1, NULL);
        }
        if (sigismember(set, SIGQUIT))
        {
            sigemptyset(action2.sa_mask);
            action2.sa_handler = SIG_DFL;
            action2.sa_flags = 0;
            sigaction(SIGQUIT, action2,NULL);
        }
        /* 设置信号集屏蔽字,此时set中的信号不会被传递给进程,暂时进入待处理状态 */
        if (sigprocmask(SIG_BLOCK, set, NULL)  0)
        {
            perror("sigprocmask");
            exit(1);
        }
        else
        {
            printf("Signal set was blocked, Press any key!");
            getchar();
        }
        /* 在信号屏蔽字中删除set中的信号 */
        if (sigprocmask(SIG_UNBLOCK, set, NULL)  0)
        {
            perror("sigprocmask");
            exit(1);
        }
        else
        {
            printf("Signal set is in unblock state\n");
        }
        while(1);
        exit(0);
    }

该程序的运行结果如下,可以看见,在信号处于阻塞状态时,所发出的信号对进程不起作用,并且该信号进入待处理状态。读者按任意键,并且信号脱离了阻塞状态后,用户发出的信号才能正常运行。这里SIGINT已按照用户自定义的函数运行,请读者注意阻塞状态下SIGINT的处理和非阻塞状态下SIGINT的处理有何不同。

问题与解决

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/89921.html

(0)

相关推荐

  • SpringCloud分布式微服务b2b2c电子商务中docker-feign-hystrix-ribbon的示例分析

    技术SpringCloud分布式微服务b2b2c电子商务中docker-feign-hystrix-ribbon的示例分析小编给大家分享一下SpringCloud分布式微服务b2b2c电子商务中docker-feign-

    攻略 2021年11月19日
  • 弯月眉,形容身材好腰细的优美句子

    技术弯月眉,形容身材好腰细的优美句子形容女子腰的句子弯月眉。
    1、看她折纤腰以微步,呈皓腕于轻纱。
    眸含春水清波流盼,头上倭堕髻斜插碧玉龙凤钗。
    香娇玉嫩秀靥艳比花娇,指如削葱根口如含朱丹,一颦一笑动人心魂。
    2、一头长

    生活 2021年10月26日
  • 基于alpine构建jdk镜像遇到的坑

    技术基于alpine构建jdk镜像遇到的坑 基于alpine构建jdk镜像遇到的坑alpine常用于作为docker的基础镜像,因为它很小,功能精简,基本上没有啥漏洞,记录一下最近用alpine作为基础

    礼包 2021年11月11日
  • Bezier Game有什么优点

    技术Bezier Game有什么优点本篇内容主要讲解“Bezier Game有什么优点”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Bezier Game有什么优点”吧!  

    攻略 2021年11月12日
  • 三戒是哪三戒,柳宗元的\”三戒\”是什么?

    技术三戒是哪三戒,柳宗元的\三戒\是什么?柳宗元的《三戒》包括《临江之麋》三戒是哪三戒、《永某氏之鼠》和 《黔之驴》 这一组三篇寓言,是作者贬谪永州时所写。题名“三戒”,可能是取《论语》“君子有三戒”之意。文前的小序,已

    生活 2021年10月22日
  • 配置H3C华三设备远程管理,SSH、Telnet等)

    技术配置H3C华三设备远程管理,SSH、Telnet等) 配置H3C华三设备远程管理(SSH、Telnet等)拓扑如下:
    注:本实验用一台华三路由器模仿真实设备,再一台host主机充当模拟器到本地计算机

    礼包 2021年12月16日