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

Linux Linux程序练习十五(进程间的通信共享内存版)的更多相关文章

  1. Linux进程间的通信

    一.管道 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: A. 管道是半双工的,数据只能向一个方向流动: B. 需要双工通信时,需要建立起两个管道: C. 只能用于父子进程或者兄弟 ...

  2. c++ 网络编程(三) LINUX/windows 进程间的通信原理与实现代码 基于多进程的服务端实现

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9613027.html 锲子:进程与线程是什么,他们的区别在哪里: 1 进程概念 进程是程序的一 ...

  3. PHP与Linux进程间的通信

    进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...

  4. linux进程间的通信之 共享内存

    一.共享内存介绍 共享内存是三个IPC(Inter-Process Communication)机制中的一个. 它允许两个不相关的进程访问同一个逻辑内存. 共享内存是在两个正在进行的进程之间传递数据的 ...

  5. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  6. 采用虚拟命名管道的字符设备和阻塞型I/O实现进程间的通信实现KWIC程序

    采用虚拟命名管道的字符设备和阻塞型I/O实现进程间的通信实现KWIC程序专业程序代写c++程序代写

  7. c 进程间的通信

    在上篇讲解了如何创建和调用进程 c 进程和系统调用 这篇文章就专门讲讲进程通信的问题 先来看一段下边的代码,这段代码的作用是根据关键字调用一个Python程序来检索RSS源,然后打开那个URL #in ...

  8. [Socket]Socket进程间的通信

    转自:http://blog.csdn.net/giantpoplar/article/details/47657303 前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket ...

  9. Nginx学习——Nginx进程间的通信

    nginx进程间的通信 进程间消息传递 共享内存 共享内存还是Linux下提供的最主要的进程间通信方式,它通过mmap和shmget系统调用在内存中创建了一块连续的线性地址空间,而通过munmap或者 ...

随机推荐

  1. google 火狐 模拟显示手机页面插件

    google      user agent switcher扩展 火狐          user agent switcher

  2. 转:能和LoadRunner匹敌的VS2010/2012Web负载测试

    原文出处:http://www.cnblogs.com/aarond/archive/2013/04/18/performance.html VS自带的Web负载测试真的很大程度上能和专业的loadr ...

  3. Java基础知识学习(一)

    部门接了新项目,后台使用Java框架play framework,前端是html,前后台通过rest交互,能够支持多端的互联网架构. 因为之前没有Java基础,前端使用的也很少,决定深入学习一下Jav ...

  4. 网络编程2--毕向东java基础教程视频学习笔记

    Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...

  5. BIEE11G常用函数及使用说明

    BIEE常用函数使用手册 1.AGGREGATE AT 此函数根据指定的级别聚合列.使用AGGREGATE AT 可确保始终在关键字AT 之后指定的级别执行度量聚合,而无论WHERE 子句如何. 语法 ...

  6. Linux 虚拟机网络适配器从E1000改为VMXNET3

    我们知道VMware的网络适配器类型有多种,例如E1000.VMXNET.VMXNET 2 (Enhanced).VMXNET3等,就性能而言,一般VMXNET3要优于E1000,下面介绍如果将Lin ...

  7. PHP6连接SQLServer2005的方法

    1.修改php.ini将extension=php_mssql.dll的注释删除保存. 修改php.in将mssql.secure_connection = Off改为mssql.secure_con ...

  8. iNeedle系统之国舜项目

    一.简介 本周公司接了一个小项目,是给北京国舜科技股份有限公司做一个HTTP相关的小功能产品.大概实现功能是将交换机的源数据通过解析,分析出HTTP包配对的request和response头,并把每对 ...

  9. 折半算法的C#实现方式-递归和非递归

    这个算法,相信大家都懂,但是不真正的手动写一遍,总觉得不得劲.这不,手动写一遍就是有不一样的效果出现了. 往左折半,还是往右走比较简单,其实这两个算法最关键的是:退出条件 min > max   ...

  10. UEFI安装Kali Linux 1.1.0记录

    现在使用Kali Linux 1.1.0, UEFI启动,使用Fcitx的拼音输入法,词库实在不爽,将就写一写. 本文地址: http://www.cnblogs.com/go2bed/p/42954 ...