sigqueue与kill详解及实例

/***********************************************************************************************
相关函数:
     #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);

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值