在UNIX中,信号(signal)被用于通知一个进程:一个特别的事件发生了。信号可以同步或异步接收,取决于事件的来源和事件的原因。信号无论同步或者异步,都遵循下面同样的模式:

  • 信号是由特定事件的发生而产生的。

  • 信号被传送到一个进程。

  • 一旦发出,信号必须被处理。

同步信号的例子包括非法存储器访问以及除法除以0.如果一个正在运行的程序执行了任一操作,一个信号就会生成。

同步信号传递到执行操作而导致产生信号的同一进程(这就是被认为是同步的原因)。

当一个信号由运行的进程之外的事件产生,那么进程就会异步的接收这个信号。这样的例子包括用特定的击键结束进程(比如ctrl + c)或者是定时器到期。通常,信号被发送到另一个进程。

一个信号可以由下列两种可能的处理程序之一来处理:

  • 默认的信号处理器
  • 用户定义的信号处理器

当处理信号时,每一个信号都有一个默认信号处理器(default signal handler),它由内核运行。这个默认操作可以被调用来处理信号的用户定义的信号处理程序( user-defined
signal handler)
覆盖。

信号可以按照不同的方式狐狸。有些信号(例如改变窗口大小)可以被忽略;其他的(例如非法的内存访问)可能是需要通过终止程序来处理的。

单线程程序的信号处理比较直接,信号总是发给进程。

不过,对于多线程程序,发送信号比较复杂,因为进程可能有多个线程,应该将信号发给谁呢??

一般来说,存在以下选项:

  1. 将信号发送到信号所应用的线程。

  2. 将信号传递到进程中的每个线程。

  3. 将信号传递给进程中的某些线程。

  4. 指定一个特定的线程来接收该进程的所有信号。

传递信号的方法取决于所产生的信号的类型。例如,需要将同步信号传递给引起信号的线程,而不需要传递给进程中的其他线程。然而,对于异步信号,情况就不那么清楚。一些异步信号——例如终止进程的信号(例如ctrl + c)——应该发送到所有线程。

发送信号的标准UNIX函数是:

kill(pid t pid, int signal)

该函数指定哪个特定的信号(即signal参数)被发送到指定的进程上(即pid参数)。大多数多线程版本的UNIX允许一个线程指定它将接受哪个信号,它将会阻止哪个信号。因此,在某些情况下,异步信号只能传递给那些没有阻止它的线程。但是,因为信号只需要处理一次,所以信号通常只发送到发现的第一个不阻止它的线程上。POSIX Pthreads提供了以下功能,它允许将信号传递到指定的线程(tid):

pthread kill(pthread t tid, int signal)

虽然Windows没有明确提供对信号的支持,但它允许我们使用异步过程调用(APC)来模拟它们。APC工具允许用户线程指定一个函数,当用户线程收到某个特定事件的通知时,该函数将被调用。正如其名称所示,APC大致相当于UNIX中的异步信号。然而,UNIX必须与如何处理多线程环境中的信号的处理做斗争,而APC工具更直接,因为APC交付给特定的线程而不是进程。

results matching ""

    No results matching ""