LINUX信号通信---不同进程间发送与接收携带字符串的信号(使用共享内存机制)

在使用sigqueue函数与sigaction函数时,
可以实现携带信息的信号的发送与接收
但是在实验的过程中发现,在父子进程,或者同一进程中发送一个带有字符串的信号是可以完成打印字符穿的工作的,但是如果在不同进程之间打印传递的字符串便会出现段错误的情况,为了解决这个问题 可以使用共享内存的方法,即在发送信号时,将我们需要传递的字符串放入共享内存中,在接收信号时,再将我们传递的数据从共享内存中将字符串读取出来

接收端

 /************************************************************************
    > File Name: IO_sigaction.c
    > 作者:YJK 
    > Mail: 745506980@qq.com 
    > Created Time: 2019年11月14日 星期四 09时29分10秒
 ***********************************************************************/
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<sys/ipc.h>

//使用共享内存读取传递的字符串 
void _sigaction_SIGUSR1(int sig,siginfo_t *info,void *ucontext)
{
	key_t key;
	int shmid;
	if((key=ftok(".",12))==-1)
	{
		perror("ftok");
		exit(EXIT_FAILURE);
	}
	if((shmid=shmget(key,1024,0777|IPC_CREAT))==-1)//创建或打开共享内存
	{
		perror("shmget");
		exit(EXIT_FAILURE);
	}
	if((info->si_ptr=(void *)shmat(shmid,NULL,0))==(void *)-1) //将共享内存挂载到当前进程
	{
		perror("shmat");
		exit(EXIT_FAILURE);
	}
	if(sig==SIGUSR1)
	printf("receive signal:%d data:%s",info->si_signo,(char *)info->si_ptr);
	//需要使用共享内存读取传递的字符串 
}
void _sigaction_SIGUSR2(int signo,siginfo_t * info,void * ucontext )
{
	if(signo==SIGUSR2)
	{
		printf("received signal:%d data:%d\n",info->si_signo,info->si_int);
	}
}
int main(int argc,char *argv[])
{
	struct sigaction act,act2;
	act.sa_sigaction=_sigaction_SIGUSR1;
	act.sa_flags=SA_SIGINFO;//对信号处理程序 提供附加信息
	sigemptyset(&act.sa_mask);//清空信号集	 	
	if(sigaction(SIGUSR1,&act,NULL)==-1)
	{
		perror("sigaction");
	}
	act2.sa_sigaction=_sigaction_SIGUSR2;
	act2.sa_flags=SA_SIGINFO;
	sigemptyset(&act2.sa_mask);
	if(sigaction(SIGUSR2,&act2,NULL)==-1)
	{
		perror("sigaction");
	}
	while(1)
	pause();
	return 0;
}

发送端

/************************************************************************
    > File Name: IO_sigqueue.c
    > 作者:YJK 
    > Mail: 745506980@qq.com 
    > Created Time: 2019年11月14日 星期四 10时45分04秒
 ***********************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<string.h>
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("-------\n");
		exit(EXIT_FAILURE);
	}
	int pid=atoi(argv[1]);
	union sigval sig_val;
	union sigval sig_val1;
	key_t key;
	int shmid;
	if((key=ftok(".",12))==-1)
	{
		perror("ftok");
		exit(EXIT_FAILURE);
	}
	if((shmid=shmget(key,1024,0777|IPC_CREAT))==-1)
	{
		perror("shmget");
		exit(EXIT_FAILURE);
	}
	if((sig_val1.sival_ptr=(void *)shmat(shmid,NULL,0))==(void *)-1)
	{
		perror("shmat");
		exit(EXIT_FAILURE);
	}
	sig_val.sival_int=100;//发送的附加信息值 
	char src[]="hello linux--\n";
	memcpy(sig_val1.sival_ptr,src,sizeof(src)); //将发送的字符串拷贝到共享内存中
	while(1)
	{
		sleep(1);
		sig_val.sival_int++;
		if(sigqueue(pid,SIGUSR1,sig_val1)==-1)
		{
			perror("sigqueue");
			exit(EXIT_FAILURE);
		}
		sleep(1);
		if(sigqueue(pid,SIGUSR2,sig_val)==-1)
		{
			perror("sigqueue");
			exit(EXIT_FAILURE);
		}
		sleep(1);
	}
	return 0;
}

运行结果
首先运行接收端,然后查看接收端的PID 在使用发送端给接收端发信号
在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值