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

c++ signal 发送信号-CSDN博客

在之前的文章中,只是说明了给指定进程发送信号,而无法携带数据,今天说明下如果和指定进程发送信号,同时可以携带简单数据。

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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值