Linux信号 三 信号发送接口集合

信号发送接口包括raise,kill,killpg,tkill,tgkill,pthread_kill,sigqueue等。

1. raise()

/**
 * raise用于向进程自身发送信号
 * 成功返回0,失败返回非0值,并置errno.
 * 只有信号处理函数执行完毕之后,raise才能返回。
 *
 * 对于单线程的程序而言,相当于调用了如下语句:
 * kill(getpid(), sig);
 * 
 * 对于多线程的程序而言,相当于调用了如下语句: 
 * pthread_kill(pthread_self(), sig);
 */
#include <signal.h>
int raise(int sig);

 2. kill()

/**
 * kill函数用于发送信号,不仅可以向特定进程组发送信号,也可以向特定进程发送信号.
 * 根据参数pid的不同,分为如下几种情况:
 * pid > 0, 发送信号给进程ID等于pid的进程。
 * pid = 0, 发送信号给调用进程所在的同一个进程组的每一个进程。
 * pid = -1, 有权限向调用进程发送信号的所有进程发送信号,init进程和进程自身除外
 * pid < -1, 向进程组-pid发送信号。
 * sig = 0,检测目标进程或目标进程组是否存在,如果返回-1并且errno为ESRCH表示目标
 * 或目标进程组不存在。
 *
 * 成功返回0,失败返回-1,并置errno
 *
 */
#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

3. killpg()

/**
 * 向进程组发送信号
 * pgrp = 0,向进程自身所在进程组发送信号。
 * pgrp <= 1,将引发未定义的行为。
 *
 * 成功返回0,失败返回-1并置errno.
 *
 */
#include <signal.h>
int killpg(int pgrp, int sig);

4. tkill() & tgkill()

/*
 * 向线程发送信号
 * 
 * 这两个都是内核提供的系统调用,glibc并没有提供对这两个系统调用的封装,如果使用
 * 这两个函数,需要采用syscall的方式:
 * ret = syscall(SYS_tkill, tid, sig);
 * ret = syscall(SYS_tgkill, tgid, sig);
 * 成功返回0,失败返回-1并置errno
 *
 * tkill是一个过时的接口,并不推荐使用它来向线程发送信号。相比之下,tgkill接口更加
 * 安全。tgkill系统调用的第一个参数tgid,为线程中主线程的线程ID,或者称为进程号。
 * 这个参数能够起到保护作用,防止向错误的线程发送信号。进程ID或线程ID是由内核负责
 * 管理,进程或线程有自己的生命周期,使用tkill发送信号有可能线程已经退出,这时候会
 * 将信号发送到不相关的进程上,为了防止出现这种情况,内核引入了tgkill系统调用,
 * 含义是向线程组ID是tgid、线程ID为tid的线程发送信号,避免发错信号。
 * 这两个函数是Linux特有的,存在一致性问题。
 *
 */
int tkill(int tid, int sig);
int tgkill(int tgid, int tid, int sig);

5. pthread_kill()

/**
 * 向同一个进程内的线程发送信号
 *
 * 成功返回0,失败返回错误码。
 * 如果sig = 0,将不发送任何信号。
 * 如果向一个已经退出的线程发送信号,将会引发未定义的行为。比如说段错误等。
 * 编译的时候加上-pthread选项
 *
 */
#include <signal.h>
int pthread_kill(pthread_t thread, int sig);

6. sigqueue()

/**
 * 向进程ID等有pid的进程发送信号和数据
 * 成功返回0,失败返回-1并置errno
 * 
 * 第三个参数为伴随数据,可以向目标进程发送一个整形数据或者指针,当目标进程注册
 * 信号处理函数使用了SA_SIGINFO标志位的时候就可以接收到该数据
 *
 *     union sigval {
 *         int   sival_int;
 *         void *sival_ptr;
 *     };
 *
 * 发送sig = 0的信号可以用来检测目标进程是否存在,返回错误码为ESRCH
 *
 *
 *
*/

#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);

参考资料:

1. 《Linux环境编程,从应用到内核》高峰,李彬著

2. man signal : http://www.man7.org/linux/man-pages/man7/signal.7.html

猜你喜欢

转载自blog.csdn.net/fuyuande/article/details/83926664