热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

unix环境高级编程信号(2)

函数kill和raise:kill函数将信号发送给进程或进程组,raise函数则运行进程向自身发送信号。kill的pid参数有以下四种不同情况

函数kill和raise:

kill函数将信号发送给进程或进程组,raise函数则运行进程向自身发送信号。

kill的pid参数有以下四种不同情况:

pid>0,将该信号发送给进程ID为pid的进程

pid==0,将该信号发送给与发送进程属于同一进程组的所有进程。

pid<0 &#xff0c;将该信号发送给进程组ID等于pid绝对值

pid&#61;&#61;-1&#xff0c;将该信号发送给发送进程有权限发送信号的所有进程。


函数alarm和pause&#xff1a;

使用alarm函数可以设置一个定时器&#xff0c;在某个时刻定时器超市&#xff0c;产生SIGALRM信号&#xff0c;若忽略或不捕捉此信号&#xff0c;则默认动作是终止调用该alarm函数的进程。

虽然SIGALRM的默认动作是终止进程&#xff0c;但大多数使用闹钟的进程捕捉此信号。

pause函数&#xff1a;使调用进程挂起直到捕捉到一个信号。

#include

int pause(void);

只有执行了一个信号处理程序并从其返回时&#xff0c;pause才返回。


利用alarm和pause函数可使自己休眠一段时间。

#include
#include static void sig_alrm(int signo)
{//nothing to do ,just return to wake up the pause
}unsigned int sleep1(unsigned int seconds)
{if(signal(SIGALAM,sig_alrm)&#61;&#61;SIG_ERR)return (seconds);alarm(seconds); //开始计时器pause(); //下一个信号会唤醒return (alarm(0));//关闭计时器&#xff0c;返回剩余时间}


这个是sleep简单而不完整的实现&#xff0c;有几个问题&#xff0c;在第一次调用alarm和pause有一个竞争条件&#xff0c;可能alarm在调用pause之前就超时&#xff0c;并调用了信号处理程序sig_alrm&#xff0c;这种情况下&#xff0c;调用pause后&#xff0c;如果没有捕捉到其他信号&#xff0c;调用者将永远被挂起。

除了用来实现sleep函数外&#xff0c;alarm还常用于对可能阻塞的操作设置时间上限值&#xff0c;例如&#xff0c;程序中有一个读低速设备的可能阻塞的操作&#xff0c;我们希望超过一定时间就停止执行该操作。


信号集&#xff1a;需要一个能够表示多个信号的数据类&#xff0c;将在sigprocmask类函数中使用这种数据类型&#xff0c;以便告诉内核不允许发生该信号集中的信号&#xff0c;

函数sigemptyset初始化由set指向的信号集&#xff0c;清除其中所有信号&#xff0c;函数sigfillset初始化由set指向的信号集&#xff0c;使其包括所有信号&#xff0c;所有应用程序在使用信号集前&#xff0c;要对该信号集调用sigemptyset或sigfillset一次&#xff0c;因为c编译程序将不赋予初值的外部变量和静态变量都初始化为0,。

一旦初始化了一个信号集&#xff0c;以后就可在信号集中增、删特定的信号。sigiaddset将一个信号添加到已有的信号集&#xff0c;sigdelset删除一个信号。

如果实现的信号数目少于一个整型量所包含的位数&#xff0c;可用一位代表一个信号的方法实现信号集。sigemptyset函数将整型设置为0&#xff0c;sigfillset函数将整型设置为1&#xff0c;sigaddset开启一位就是将该位设置为1&#xff0c;sigdelset关闭一位将该位设置为0。sigismember测试一个指定的位&#xff0c;因为没i有信号编号为0&#xff0c;从信号编号减一得到要处理位的位编号。


函数sigaction&#xff1a;检查或修改与指定信号相关联的处理动作&#xff0c;此函数取代unix早起的signal函数。

参数signo是信号编号&#xff0c;若act指针非空&#xff0c;则要修改其动作&#xff0c;若oact指针非空&#xff0c;则系统经过oact指针返回该信号的上一个动作。此函数使用以下结构


函数sigsetjmp和siglongjmp

之前用于非局部转移的setjmp和longjmp函数&#xff0c;在信号处理函数中经常调用longjmp函数以返回到程序的主循环中&#xff0c;但是调用longjmp有个问题&#xff0c;当捕捉到一个信号时&#xff0c;进入信号捕捉函数&#xff0c;此时当前信号被自动加到进程的信号屏蔽字中&#xff0c;这阻止了后来产生的这种信号中断该信号处理程序。


函数abort&#xff1a;使程序异常终止

此函数将SIGABRT信号发送给调用进程&#xff0c;在进程终止之前由其窒息感所需的清理操作&#xff0c;如果进程并不在信号处理程序中终止自己&#xff0c;那么当信号处理程序返回时&#xff0c;abort终止该进程。


函数sleep&#xff1a;

此函数使调用进程被挂起&#xff0c;直到满足下面两个条件之一&#xff1a;

1.以及过了seconds所指定的墙上时钟时间

2.调用进程捕捉到一个信号并从信号处理程序返回。

尽管sleep函数可以用alarm函数实现&#xff0c;但这并不是必须的。使用alarm函数可鞥两个函数之间还会互相影响。

nanosleep函数&#xff1a;与sleep函数类似&#xff0c;但提供了纳秒级的精度。


作业控制信号&#xff1a;

在那么多信号中&#xff0c;与作业控制有关的是6个&#xff1a;

SIGCHLD 子进程已停止或终止

SIGCONT 如果进程已停止&#xff0c;则使其继续运行

SIGSTOP 停止信号

SIGTSTP 交互式停止信号

SIGTTIN 后台进程组成员读控制终端

SIGTTOU 后台进程组成员写控制终端

除了SIGCHLD之外&#xff0c;大多数应用程序并不处理这些信号&#xff0c;交互式shell则通常会处理这些信号的所有工作&#xff0c;当键入挂起字符&#xff08;crtl&#43;Z&#xff09;&#xff0c;SIGTSTP被送至前台进程组的所有进程&#xff0c;当我们通知在前台或后台恢复运行一个作业时&#xff0c;shell向该作业的所有进程发送SIGCONT信号。

在作业控制信号之间还存在某种交互&#xff0c;比如当一个进程产生4种停止信号&#xff08;SIGTSTP、SIGSTOP、SIGTTIN或SIGTTOU&#xff09;中的任意一种时&#xff0c;对该进程的任一未决信号SIGCONT信号就被丢弃&#xff0c;与此类似&#xff0c;当对一个进程产生SIGCONT信号时&#xff0c;对同一进程的任一未决停止信号被丢弃。


信号名和编号&#xff1a;

信号名和编号之间如何进行映射&#xff0c;系统提供数组&#xff1a;

extern char  *sys_siglist[]&#xff1b;

数组下标是信号编号&#xff0c;数组中的元素是指向信号名符串的指针



推荐阅读
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 如何用JNI技术调用Java接口以及提高Java性能的详解
    本文介绍了如何使用JNI技术调用Java接口,并详细解析了如何通过JNI技术提高Java的性能。同时还讨论了JNI调用Java的private方法、Java开发中使用JNI技术的情况以及使用Java的JNI技术调用C++时的运行效率问题。文章还介绍了JNIEnv类型的使用方法,包括创建Java对象、调用Java对象的方法、获取Java对象的属性等操作。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
author-avatar
b87968557
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有