linux有关信号的FAQ

1、为什么会出现系统调用被中断的情况?

  进程在执行一个低速系统调用而阻塞期间捕捉到一个信号时,该系统调用就被中断不再继续执行。该系统调用返回出错,其errno被设置为EINTR。这样处理的理由是:因为一个信号发生了,进程捕捉到了它,这意味着已经发生了某种事情,所以是个唤醒阻塞的系统调用的好机会。

 

2、不可重入函数的原因?

  (a)它们使用静态的数据结构;(b)调用mallocfree;(c)它们是标准IO函数。

 

3、在对某个信号解除阻塞之前,如果这个信号发生了多次,那就如何处理?

  UNIX只递送这种信号一次,其它信号不进行排队,只被简单的丢弃。

 

4、一个进程能发送信号给哪些进程?

  如果这个进程拥有超级用户权限,这可以发给任何进程;如果这个进程是普通用户进程,则发送者的实际或者有效用户ID必须等于接收者的实际或有效用户ID。有一个特例是,如果被发送的信号是SIGCONT,则进程可将它发送给属于同一会话的任何其他进程。

 

5、信号传递有两个阶段?

  一个是信号产生:内核更新目标进程的数据结构以表示一个新信号已被发送;另一个是信号传递:内核强迫目标进程通过以下方式对信号做出反应:或改变目标进程的指向状态,或开始执行一个特定的信号处理程序,或者两者都是。已经产生但还没有传递的信号称为挂起信号。

 

6、信号处理函数是否必须是可重入的?

  当信号执行一个信号处理程序的函数时,通常“屏蔽”相应的信号,即自动阻塞这个信号直到处理程序结束。因此,所处理的信号的另一次出现不能中断信号处理程序,所以,信号处理函数不必是可重入的。

 

7、信号处理程序在多线程中是怎样调用的?

  每个线程都有自己的挂起信号掩码(哪些信号正等待被传递)和阻塞信号掩码(哪些信号被阻塞)。只能给多线程应用发信号,而不能给单个线程发信号。每个发生给多线程应用的信号仅传送给一个线程,这个线程是由内核从不阻塞该信号的线程中随意选择出来的。如果向多线程应用发生了一个致命的信号,那么内核将杀死该应用的所有线程,而不仅仅是杀死接收信号的那个线程。

 

8、一个信号处理程序可以打断另一个信号处理程序的执行吗?

  可以的,只要这两个信号处理程序不是同一个就行。apue中讲解alarmpause函数中举了一个例子,在该例子中SIGINT的处理程序就被SIGALRM处理程序中断了。

 

9、执行完某个信号的处理程序后,该信号的处理会不会恢复为系统默认的动作?

  不会,只有早期版本的系统会,现在的不会了。

 

10struct signal中的sa_handlesa_sigaciton字段的关系?

  struct signal结构中的sa_handlersa_sigaction字段可能使用同一存储区,所以应用程序只能一次使用这两个字段中的一个。通常我们使用的是第一个字段,如果设置了SA_SIGINFO标志,则是使用sa_sigaction字段。

 

11、调用sigaction函数时设置的信号屏蔽集是在信号处理函数运行时直接设置为进程的信号屏蔽集还是并入进程的信号屏蔽集?

  在调用处理函数之前将信号屏蔽集并入进程的信号屏蔽集,函数退出后再恢复进程先前的信号屏蔽集。

 

12、我们知道在调用信号处理程序之前会将当前处理的信号加入到信号屏蔽集中,如果在信号处理程序中使用longjmp跳出信号处理程序,那么信号屏蔽集是否会恢复到调用信号处理程序之前的状态?

  POSIX.1并没有对此说明,不过我们可以使用函数sigsetjmpsiglongjmp来显示解决这个问题。如果在调用sigsetjmp时传递的savemask参数不为0,则sigsetjmpenv中保存进程的当前信号屏蔽集。调用siglongjmp时,如果带非0 savemasksigsetjmp调用已经保存了env,则siglongjmp从其中恢复保存的信号屏蔽集。

 

13、哪些信号是不能被捕获或忽略的?

  SIGKILLSIGSTOP是不能被捕获或忽略的。

 

14、abort的作用是什么?

发送SIGABRT信号给进程(进程不应该忽略此或阻塞该信号),abort确保进程被终止前对所有打开标准I/O流进行冲洗和关闭,除非进程自己捕获了SIGABRT处理函数,并且调用_exit让进程终止。

 

15、kill使其为调用者产生信号,是不是kill返回前对应的信号就传送给了该进程?

  不一定,首先要保证该信号不被阻塞,其次保证该进程没有其它未决未阻塞的信号。如果kill产生的信号是不被阻塞的,则kill返回前该信号(或某个未决、未阻塞的信号)就被传送给了该进程。

 

16、system对信号是怎么处理的?

  system会忽略SIGINTSIGQUIT,阻塞SIGCHLD。忽略SIGINTSIGQUIT这两个信号是保证调用system产生的子进程捕获这两个信号,而调用system的进程则不应该捕获这两个信号。阻塞SIGCHLD保证我们能正确的获得system产生的子进程的终止状态。

 

17、fork系统调用后子进程会继承信号屏蔽掩码,信号处理函数吗?

  会的,不过未处理的信号集会设置为空集。

 

18、waitpid函数什么情况下会返回?

  如果该函数等待的进程或进程组状态改变了就会返回,如进程终止了(不管子进程是否发生SIGCHLD信号给父进程),或者该函数等待的进程或进程组不存在了,则会出错返回。

 

19、一个停止的进程接到SIGCONT信号时,会怎样?

  当对一个停止的进程产生一个SIGCONT信号时,该进程就继续运行,即使该信号是被阻塞或忽略的也是如此。

 

20、linux下的作业控制命令有哪些?

  fgbgjobs&ctrl + z都是跟作业有关的命令。& 最经常被用到,这个用在一个命令的最后,可以把这个命令放到后台执行;ctrl + z,可以将一个正在前台执行的命令放到后台,并且暂停;jobs,查看当前有多少在后台运行的命令;fg,将后台中的命令调至前台继续运行,如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid);bg,将一个在后台暂停的命令,变成继续执行,如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

posted @ 2014-03-02 13:16  在于思考  阅读(1117)  评论(0编辑  收藏  举报