05 2016 档案

摘要:在10.8节中我们讲到许多UNIX系统并不支持信号的排队,随着POSIX.1增加了实时扩展,一些系统开始支持信号队列,在SUSv4中,信号队列功能已经从实时扩展中移到了基本规范中了。 通常来说,一个信号只能携带一个bit的信息:即是信号本身。除了排队的信号之外,这些扩展还允许应用程序在信号发送的同时传递更多的信息,这些信息被嵌入到了一个siginfo结构中,连同系统提供的信息一起,应用程序可... 阅读全文
posted @ 2016-05-30 00:08 U201013687 阅读(686) 评论(0) 推荐(0)
摘要:我们已经在本书中多次使用了函数sleep,我们也在图10.7以及图10.8中展示了两个有缺陷的sleep函数的实现。 #include unisgned int sleep(unsigned int seconds); Returns:0 or number of unslept seconds. 该函数会造成进程挂起直到如下两个条件中至少一个为止: seconds指定的系统时间... 阅读全文
posted @ 2016-05-29 21:51 U201013687 阅读(5584) 评论(0) 推荐(0)
摘要:在8.13节中,我们展示了一个system函数的实现,在哪一个版本中,我们并没有对信号做任何处理。POSIX.1要求system函数需要忽略SIGINT以及SIGQUIT信号,并且阻塞信号SIGCHLD.在展示一个正确处理这些信号的函数实现之前,让我们一起看一下为什么需要担心信号的处理。 Example 图10.26中显示的例子使用了8.13中的system函数调用了函数vi(1)编辑器.... 阅读全文
posted @ 2016-05-28 12:17 U201013687 阅读(296) 评论(0) 推荐(0)
摘要:我们早些时候提到函数abort能够造成程序的非正常终止。 #include void abort(void); This function never returns. 该函数会发送一个信号SIGABRT到调用进程。(进程不应该忽略这一信号),ISO C指出调用函数abort将会通过调用函数raise(SIGABRT)向主机环境发送一个不成功的终止通知。(ISO C states t... 阅读全文
posted @ 2016-05-26 07:29 U201013687 阅读(504) 评论(0) 推荐(0)
摘要:我们已经学习了如何修改进程的信号掩码,实现指定信号的阻塞与接触阻塞。我们可以使用这一技术来保护临界区域的代码(当在这一段区域内执行代码的时候哦,我们不希望被信号中断),但是如果我们想要接触一个信号的阻塞,然后进入暂停状态,等待之前阻塞的信号的出现呢?假设指定的信号是SIGINT,可能会采用如下的方式来实现,但是确实错误的: sigset_t newmask,oldmask;sigem... 阅读全文
posted @ 2016-05-24 22:55 U201013687 阅读(509) 评论(0) 推荐(0)
摘要:在7.10节中,我们讲述了setjmp以及longjmp函数,这两个函数用于远程跳转。其中longjmp函数进场在信号处理函数中被调用,用于返回到进程的主循环中去,而不是从信号处理函数中返回。 但是使用函数longjmp有一个问题,当一个信号被捕获的时候,信号处理函数被执行,当前信号将被自动增加到进程的信号掩码中去。这样做的目的是为了防止后续的信号中断当前信号处理函数的执行,如果我们调用lo... 阅读全文
posted @ 2016-05-22 23:36 U201013687 阅读(654) 评论(0) 推荐(0)
摘要:函数sigaction允许我们获取或者是修改(或者获取并修改)与特定信号相关联的处理函数,该函数替代了早期的UNIX系统发布版中的函数signal,实际上,在本节末尾,我们将会使用sigaction来实现一个signal函数。 #include int sigaction(int signo, const struct sigaction *restrict act, struct siga... 阅读全文
posted @ 2016-05-22 23:35 U201013687 阅读(478) 评论(0) 推荐(0)
摘要:函数sigpending被阻塞发送并且当前被调用该函数的进程挂起的信号,这个信号集通过参数set返回. #include int sigpending(sigset_t *set); Returns:0 if OK,-1 on error. Example #include "apue.h"static void sig_quit(int);int main(void){ ... 阅读全文
posted @ 2016-05-22 23:34 U201013687 阅读(289) 评论(0) 推荐(0)
摘要:在10.8节中我们提到进程的掩码是一个当前阻塞信号发送到进程的信号集合。一个进程可以查看其信号掩码,改变其信号掩码,或者同时执行这两个操作,通过调用函数sigprocmask来实现上述要求. #include int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); return:0... 阅读全文
posted @ 2016-05-22 23:34 U201013687 阅读(447) 评论(0) 推荐(0)
摘要:我们需要使用一种数据类型来存储多个信号,这种类型称为信号集,我们将在函数sigprocmask等函数中使用这些数据结构(下一节中),用于告知内核不要允许集合中的信号出现,正如我们早些时候提到的,不同信号的数量可能会超过一个整形变量的Bit数量,所以通常来说,我们不能使用整形变量中的每一个Bit来存储每一个信号。POSIX.1定义了数据结构sigset_t用存储信号集,并且允许如下五个函数对其进... 阅读全文
posted @ 2016-05-22 23:33 U201013687 阅读(185) 评论(0) 推荐(0)
摘要:alarm函数pause函数ExampleExampleExampleExample alarm函数 alarm函数允许我们设置一个在未来的某一时刻终止的定时器,当定时器终止的时候,SIGALRM信号就被发出,如果我们忽略或者不捕获这一信号的话,该信号的默认行为是终止进程. #include unsigned int alarm(unsigned int seconds); Ret... 阅读全文
posted @ 2016-05-22 23:33 U201013687 阅读(857) 评论(0) 推荐(0)
摘要:kill函数用于发送信号给一个进程或者是一个进程组,函数raise允许进程发送一个信号给自身。 raise函数最开始定义与ISO C中,POSIX.1为了与兼容ISO C标准,于是包含了函数raise,但是POSIX.1将函数raise的特性扩展到了线程处理(我们将在12.8中讨论线程是如何与信号发生交互的),因为ISO C并不处理多进程,它并不能定义向kill这样的函数,因为kill函数... 阅读全文
posted @ 2016-05-22 23:32 U201013687 阅读(498) 评论(0) 推荐(0)
摘要:我们需要定义一些术语来继续信号的讨论,首先,信号是在造成信号的事件出现的时候由进程产生或者被发送到进程的,该事件可能是硬件错误(比如说除零错误),软件条件(比如说alarm设置的时间达到),或者是终端信号,或者是kill函数的调用,当信号产生的时候,内核通常在进程表中设置一些标志。 我们所说的”信号被发送到一个进程”是在进程准备执行信号处理函数的时候,在信号生成和被发送之间的时候,信号被称为pe... 阅读全文
posted @ 2016-05-22 23:31 U201013687 阅读(224) 评论(0) 推荐(0)
摘要:经常混淆的两个信号就是SIGCLD以及SIGCHLD,信号SIGCLD源于System V,该信号的含义与源自BSD的信号SIGCHLD不一致。同时POSIX.1信号也称为SIGCHLD.源自BSD的信号SIGCHLD的语义比较正常,当该信号出现的时候,表示子进程的状态发生了变化,然后我们需要调用一个wait函数来查看究竟发生了什么。 System V对于SIGCLD的处理历史以来都与其他信号不... 阅读全文
posted @ 2016-05-22 23:31 U201013687 阅读(480) 评论(0) 推荐(0)
摘要:当一个信号捕获到并开始被进程处理的时候,进程正常执行的指令序列将被信号处理函数临时中断,进程立即转到信号处理函数中开始执行,如果信号处理函数返回(而不是调用exit或者是longjmp等),然后在进入信号处理函数之前进程正在执行的指令序列将会接着执行,但是在信号处理函数中,我们无法获知在信号被捕获的时候进程正在执行那一段代码,如果进程正在使用函数malloc在其堆上分配额外的内存的过程中会发生什么... 阅读全文
posted @ 2016-05-22 23:30 U201013687 阅读(334) 评论(0) 推荐(0)
摘要:早期UNIX系统的一个特点就是:当进程被阻塞再一个“slow”的系统调用中的时候如果捕获到一个信号,系统调用就会被中断,然后系统调用返回一个错误,其中errno被设置为EINTR.这可以实现使用一些事件的发生来唤醒被阻塞的系统调用。 为了支持这一特性,系统调用被分为两类:slow的系统调用,以及其他系统调用,所谓的slow系统调用是指可能永远阻塞的系统调用,包括如下系统调用: 读操作可能会永... 阅读全文
posted @ 2016-05-22 23:29 U201013687 阅读(856) 评论(0) 推荐(0)
摘要:在早期版本的UNIX系统中(比如说版本7),信号是不可靠的,意思是说信号可能丢失:一个信号出现,但是进程可能永远也不知道它,Aslo,a process had little conrol over a signal: a process could catch the signal or ignore it, 有时候,我们希望告知内核阻塞一个信号:不要忽略它,当信号出现的时候记住,然后在进程准备... 阅读全文
posted @ 2016-05-22 23:28 U201013687 阅读(246) 评论(0) 推荐(0)
摘要:UNIX系统的信号特性的最简单的接口就是signal函数: #include void (*signal(int signo, void(* func)(int)))(int); Returns:previous disposition of signal(see following)if OK,SIG_ERR on error. 函数signal由ISO C定义,并不涉及到多进程... 阅读全文
posted @ 2016-05-22 23:26 U201013687 阅读(360) 评论(0) 推荐(0)
摘要:首先,每一个信号都有一个名字,这些名字都是使用相同的三个字母SIG 开始的。举例来说,SIGABRT是当进程调用数abort的时候生成的终止信号。SIGALRM是当函数alaram设置的定时时间到的时候生成的alarm信号。版本7已经有了15中信号;SVR4以及4.4BSD有31种不同的信号,FreBSD 8.0支持32中不同的信号:Mac OS X10.6.8以及Linux3.2.0各支持31中... 阅读全文
posted @ 2016-05-22 23:25 U201013687 阅读(489) 评论(0) 推荐(0)
摘要:信号是软件中断。许多重要的应用程序都需要处理信号,信号提供了一种异步事件处理的方法—举例来说,一个用户在终端上键入中断按键或者是pipeline中下一个程序提前终止。 信号在早期UNIX系统中就已经有提供了,但是系统中的信号模型并不可靠,信号可能丢失,当程序中执行一段关键区域的代码的时候,很难去关闭指定的信号。BSD4.3以及SVR3都对信号模型进行了修改,增加了称为可靠信号reliable s... 阅读全文
posted @ 2016-05-22 23:25 U201013687 阅读(160) 评论(0) 推荐(0)