sigqueue与kill详解及实例

xiaoxiao2021-02-28  91

/*********************************************************************************************** 相关函数: #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); }
转载请注明原文地址: https://www.6miu.com/read-84764.html

最新回复(0)