C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > c++ signal携带数据的接收与发送

详解c++中signal信号携带数据的接收与发送

作者:年少轻狂且纵马

这篇文章主要为大家详细介绍了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携带数据的接收与发送内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文