sys_tkill函数主要是通过pecific_send_sig_info()函数实现的,下面我们看一下pecific_send_sig_info()(kernel/signal.c)的定义:

static int
specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
 int ret = 0;

 if (!irqs_disabled())
  BUG();
 assert_spin_locked(&t->sighand->siglock);

 if (((unsigned long)info > 2) && (info->si_code == SI_TIMER))
  /*
   * Set up a return to indicate that we dropped the signal.
   */
  ret = info->si_sys_private;
 /*信号被忽略*/
 /* Short-circuit ignored signals.  */
 if (sig_ignored(t, sig))
  goto out;

 /* Support queueing exactly one non-rt signal, so that we
    can get more detailed information about the cause of
    the signal. */
 if (LEGACY_QUEUE(&t->pending, sig))
  goto out;

 ret = send_signal(sig, info, t, &t->pending);//实际的发送工作
 if (!ret && !sigismember(&t->blocked, sig))
  signal_wake_up(t, sig == SIGKILL);
out:
 return ret;
}

  首先调用sig_ignored检查信号是否被忽略,然后检查发送的信号是不是普通信号,如果是普通信号,需要根据信号位图来检查当前信号队列中是否已经存在该信号,如果已经存在,对于普通信号不需要做任何处理。然后调用send_signal来完成实际的发送工作,send_signal()是信号发送的重点,除sys_tkill之外的函数,终都是通过send_signal()来完成信号的发送工作的。

  这里注意到想send_signal()传递的参数时t->pending,也是连接Private Signal Queue的那条链。后,如果发送成功调用signal_wake_up()来唤醒目标进程,这样可以保证该进程进入绪状态,从而有机会被调度执行信号处理函数。