/***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
相关函数:
#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函数发送信号。
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);
}