详解c++中signal信号携带数据的接收与发送
作者:年少轻狂且纵马
在之前的文章c++ signal 发送信号中,只是说明了给指定进程发送信号,而无法携带数据,今天说明下如果和指定进程发送信号,同时可以携带简单数据。
1. 发送端使用的接口
int sigqueue(pid_t pid, int sig, const union sigval value);
参数说明
@pid:给指定进程的pid
@sig:发送的信号,为如下1-64
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
@value:主要为下边的联合体赋值,简单的整形可以通过sival_int 直接赋值,其他大的数据,则需要通过将地址赋值给sival_ptr。
union sigval { int sival_int; void *sival_ptr; };
返回值:
成功返回0,否则返回-1
2. 接收端使用的接口
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
参数说明:
@signum: 则为接收的信号,与发送时的信号保持一致
@act:主要用来注册我们的接收函数
@oldact:一般设置为NULL
struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); };
@@sa_handler: // 只是接收信号的函数
@@sa_sigaction:// 接收信号,而且接收携带的数据,同时设置sa_flags为SA_SIGINFO
@@sa_mask: 用来设置处理函数是否阻塞
这里只是简单说明下,详细问问度娘
发送端使用示例
#include <iostream> #include <string> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <signal.h> void DoCmdGetPid(const std::string& cmd, std::string& stringPid) { FILE *pFile = popen(cmd.c_str(), "r"); char *buff = new char[256]; memset(buff, 0, sizeof(buff)); fread(buff, 1, sizeof(buff), pFile); stringPid = buff; pclose(pFile); delete[] buff; } void SendSig() { const std::string& procName = "recv"; std::string cmd = "ps -a | grep " + procName + " |grep -v grep | awk '{print $2}'"; std::string strPid; DoCmdGetPid(cmd, strPid); if (strPid.empty()) { std::cout << "not process\n"; return; } union sigval sv; sv.sival_int = 66; int res = sigqueue(std::stoi(proc_pid), 38, sv); printf("res:%d\n", res); return; } int main() { while (1) { SendSig(); sleep(5); } return 0; }
接收端使用示例
#include <signal.h> #include <unistd.h> #include <iostream> void signal_handler(int s, siginfo_t* pSi, void* ucontext) { if (SIGRTMIN + 4 == s) { std::cout << "recv sig38\n"; printf("value:%d\n", pSi->si_value.sival_int); printf("value:%d\n", pSi->si_int); } } int main() { struct sigaction act; act.sa_sigaction = signal_handler; act.sa_flags = SA_SIGINFO; if (sigaction(SIGRTMIN + 4, &act, nullptr) < 0) {} while(true) { std::cout << "waiting signal..." << std::endl; sleep(3); } return 0; }
到此这篇关于详解c++中signal信号携带数据的接收与发送的文章就介绍到这了,更多相关c++ signal携带数据的接收与发送内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!