sigqueue与kill详解及实例

来源:互联网 发布:java list map 编辑:程序博客网 时间:2024/06/08 13:37
/***********************************************************************************************相关函数:     #include <sys/types.h>     #include <signal.h>     int kill(pid_t pid, int sig);     int sigqueue(pid_t pid, int sig, const union sigval value);***********************************************************************************************/    kill 与 sigqueue两个函数功能都是向进程发送信号不同的是sigqueue函数可以传递用户参数到信号处理函数中如果要使用sigqueue函数,则必须将sigaction结构体中的flags设置为SA_SIGINFO同时将信号处理函数的地址赋值给sa_sigaction。参数解释:    pid:    进程pid    sig:    要发送的信号编码    sigval: 一个共用体, 可以传递一个整形参数,            如果要传递多个参数时,可以将其包装在一个结构体中然后赋给sival_ptr            union sigval {                int sival_int;                void *sival_ptr;            };
实例1:    使用kill函数发送信号.#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <signal.h>void sig_quit(int signo){    if (SIGQUIT == signo) {        printf("receive SIGQUIT\n");    }}int main(void){    sigset_t zeromask;    sigemptyset(&zeromask);    /****使用自定义信号捕捉函数捕捉SIGQUIT信号*****/    if (mysignal(SIGQUIT, sig_quit) == SIG_ERR) {        perror("mysignal error");        return EXIT_FAILURE;    }    /**     * sigsuspend函数的工作原理是:     * 首先将之前设置为阻塞的信号设置为非阻塞,及捕捉那些信号     * 然后调用pause函数挂起,直到直到接收到任意信号,并从此信号捕捉函数返回后才返回。     **/    sigsuspend(&zeromask);    return EXIT_SUCCESS;}
实例2:    调用sigqueue函数发送信号。#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>struct value{    pid_t pid;    union sigval si_val;};void *thread_func(void *arg){    sigqueue(((struct value*)arg)->pid, SIGUSR1,  ((struct value*)arg)->si_val);    pthread_exit((void*)EXIT_SUCCESS);}void sig_usr(int signo, siginfo_t *info, void *context){    if (SIGUSR1 == signo) {        printf("receive SIGUSR1!\n");        printf("info.si_int = %s\n", (char*)info->si_ptr);    }}int main(void){    char arg[] = "hello world!";    struct value v;    v.pid = getpid();  //得到进程id    v.si_val.sival_ptr = (void*)arg;  //需要传递的参数    sigset_t zeromask;    sigemptyset(&zeromask);    struct sigaction act;    act.sa_sigaction = sig_usr;  //信号处理程序    sigemptyset(&act.sa_mask);    act.sa_flags = SA_SIGINFO;   //设置sa_flags的标志位SA_SIGINFO, 程序将自动调用sa_sigaction所指向的信号处理函数    if (sigaction(SIGUSR1, &act, NULL) < 0) {        perror("sigaction error");        return EXIT_FAILURE;    }    int err;    pthread_t tid;    /****创建线程,在线程中向进程发送信号****/    err = pthread_create(&tid, NULL, thread_func, (void*)&v);      if (err != 0) {        perror("pthread_create error");        return EXIT_FAILURE;    }    sigsuspend(&zeromask);    /****等待线程退出***/    pthread_join(tid);    return EXIT_SUCCESS;}
实例1中使用到的mysignal函数源码:#include <stdlib.h>#include <signal.h>typedef void sigfunc(int);sigfunc *mysignal(int signum, sigfunc *func){    struct sigaction act, oldact;    act.sa_handler = func;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;    if (SIGALRM == signum) {#ifndef SA_INTERRUPT        act.sa_flags = SA_INTERRUPT;#endif    } else {        /***处SIGALRM信号外,都尝试重启系统调用***/        act.sa_flags = SA_RESTART;    }    if (sigaction(signum, &act, &oldact) < 0) {        return (SIG_ERR);    }    return (oldact.sa_handler);}
原创粉丝点击