/** 题目:
* 编写程序,要去实现如下功能:
父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值进行打印。
提示:用sigqueue和sigaction实现
**/#include#include#include#include#include#include#include#include#include
/* 分析:* 子进程2将pid存入共享内存区,子进程1从共享内存区中读取子进程2的pid,向子进程2发送带数据的信号
**/
//子进程2信号安装回调函数
void handler(int sign, siginfo_t * info, void *p)
{if (sign ==SIGRTMIN)
{
printf("子进程2接收到数据%d",info->si_value.sival_int);//向父进程发送信号
if (sigqueue(getppid(), SIGRTMIN, info->si_value) != 0)
{
perror("sigqueue() err");return;
}//退出子进程2
printf("子进程2 quit");
exit(0);
}
}//父进程信号安装回调函数
void handlerf(int sign, siginfo_t * info, void *p)
{if (sign ==SIGRTMIN)
{//打印信号值
printf("父进程接收的值是%d", info->si_value.sival_int);
}
}int main(int arg, char *args[])
{//创建共享内存区
int shmid = shmget(IPC_PRIVATE, sizeof(int), 0666);if (shmid == -1)
{
printf("shmget() failed !");return -1;
}
pid_t pid= 0;
pid=fork();if (pid == -1)
{
perror("fork() err");return -1;
}if (pid == 0)
{//子进程1
printf("子进程1的pid=%d", getpid());int *pid2 =NULL;//子进程1附加到共享内存区
pid2 = (int *) shmat(shmid, 0, 0);if ((int) pid2 == -1)
{
perror("shmat() err");return -1;
}//等待进程2向共享内存区写入数据
while (*pid2 == 0)
{//等待共享内存区中有数据
sleep(1);
}//向进程2发送可靠信号
union sigval v1;
v1.sival_int= getpid() * 2;if (sigqueue(*pid2, SIGRTMIN, v1) != 0)
{
perror("sigqueue() err");return -1;
}//发送完信号后,进程1退出
printf("子进程1 exit");
exit(0);
}
pid=fork();if (pid == -1)
{
perror("fork() err");return -1;
}if (pid == 0)
{//子进程2
printf("子进程2的pid=%d", getpid());//安装信号SIGRTMIN
structsigaction act;
act.sa_sigaction=handler;
sigemptyset(&act.sa_mask);
act.sa_flags=SA_SIGINFO;if (sigaction(SIGRTMIN, &act, NULL) != 0)
{
printf("sigaction() failed !");return -1;
}int *mypid =NULL;//子进程2附加到共享内存区
mypid = (int *) shmat(shmid, 0, 0);if ((int) mypid == -1)
{
perror("shmat() err");return -1;
}//将子进程2的pid放到共享内存区,操作私有共享内存区,映射到系统共享内存区
*mypid =getpid();//等待子进程1向自己发送信号
while (1)
{
printf("子进程2 sleep");
sleep(1);
}
}//父进程//安装信号SIGRTMIN
structsigaction act;
act.sa_sigaction=handlerf;
sigemptyset(&act.sa_mask);
act.sa_flags=SA_SIGINFO;if (sigaction(SIGRTMIN, &act, NULL) != 0)
{
printf("sigaction() failed !");return -1;
}int ret=0;//等待子进程
while(1)
{
ret=wait(NULL);
printf("子进程pid=%d",ret);if(ret==-1)
{if(errno==EINTR)
{continue;
}break;
}
}//释放共享内存区
if (shmctl(shmid, IPC_RMID, NULL) != 0)
{
printf("shmctl() failed!");
}
printf("game is over !");return 0;
}/** 出错总结:gdb报错:shmat() err: Invalid argument,意思是shmat()参数不正确
* 经过半天分析,发现我在父进程中没有wait子进程,直接调用了shmctl()函数,把共享内存给释放了,所以报错
**/