在使用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 在使用发送端给接收端发信号