2017-2018-1 20155317 IPC
2017-2018-1 20155317 IPC
- 共享内存
共享内存主要是通过映射机制实现的。以window系统调用为例子:Windows 下进程的地址空间在逻辑上是相互隔离的,但在物理上却是重叠的。所谓的重叠是指同一块内存区域可能被多个进程同时使用。当调用 CreateFileMapping 创建命名的内存映射文件对象时,Windows 即在物理内存申请一块指定大小的内存区域,返回文件映射对象的句柄 hMap。为了能够访问这块内存区域必须调用 MapViewOfFile 函数,促使 Windows 将此内存空间映射到进程的地址空间中。当在其他进程访问这块内存区域时,则必须使用OpenFileMapping 函数取得对象句柄 hMap,并调用 MapViewOfFile 函数得到此内存空间的一个映射。这样一来,系统就把同一块内存区域映射到了不同进程的地址空间中,从而达到共享内存的目的。
#include <iostream>
#include <windows.h>
#include <string>
#include <cstring>
using namespace std; int main() {
string strMapName("ShareMemory"); // 内存映射对象名称
string strComData("This is common data!"); // 共享内存中的数据
LPVOID pBuffer; // 共享内存指针 // 首先试图打开一个命名的内存映射文件对象
HANDLE hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, , strMapName.c_str());
if (NULL == hMap)
{
// 打开失败,创建之
hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,,strComData.length()+,strMapName.c_str());
// 映射对象的一个视图,得到指向共享内存的指针,设置里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, , , );
strcpy((char*)pBuffer, strComData.c_str());
cout << "写入共享内存数据:" << (char *)pBuffer << endl; }
else
{
// 打开成功,映射对象的一个视图,得到指向共享内存的指针,显示出里面的数据
pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, , , );
cout << "读取共享内存数据:" << (char *)pBuffer << endl; } getchar(); // 注意,进程关闭后,所有句柄自动关闭,所以要在这里暂停 // 解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(pBuffer);
::CloseHandle(hMap);
system("pause");
return ; }
- 管道
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/wait.h>
int pid1,pid2; int main()
{
int fd[];
char outpipe[],inpipe[];
while((pid1 = fork()) == -);
if(pid1 == )
{
lockf(fd[], , );
sprintf(outpipe,"\n child process 1 is sending message!\n");
write(fd[], outpipe, );
sleep();
lockf(fd[], , );
exit();
}
else
{
while((pid2 = fork()) == -);
if(pid2 == )
{
lockf(fd[], , );
sprintf(outpipe,"\n child process 2 is sending message !\n");
write(fd[], outpipe, );
sleep();
lockf(fd[], , );
exit();
}
else
{
wait();
read(fd[], inpipe, );
printf("%s\n",inpipe);
wait();
read(fd[], inpipe, );
printf("%s\n",inpipe);
exit();
}
}
}
- FIFO
FIFO与管道类似,它们最大的差别是,FIFO在文件系统中拥有一个名称,并且其打开方式与打开一个普通文件是一样的,这样就能够将FIFO用于非相关进程之间的通信。
#include<sys/types.h>
.#include<sys/stat.h>
.#include<errno.h>
.#include<fcntl.h>
.#include<stdio.h>
.#include<stdlib.h>
.#include<string.h>
.#define FIFO_SERVER "./myfifo"
.main(int argc,char** argv)
.{
. int fd;
. char w_buf[];
. int nwrite;
. if(fd==-)
. if(errno==ENXIO)
. printf("open error;no reading process\n");
. fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,);
. if(argc==)
. printf("Please send something\n");
. strcpy(w_buf,argv[]);
. if((nwrite=write(fd,w_buf,))==-)
. {
. if(errno==EAGAIN)
. printf("The FIFO has not been read yet. Please try later\n");
. }
. else
. printf("write %s to the FIFO\n",w_buf);
.}
- 信号
信号实际上是软中断,既然是中断那么信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。 信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
void new_op(int,siginfo_t*,void*);
int main(int argc,char**argv)
{
struct sigaction act;
union sigval mysigval;
int i;
int sig;
pid_t pid;
char data[];
mset(data,,sizeof(data));
for(i=; i < ; i++)
data[i]='';
mysigval.sival_ptr=data;
sig=atoi(argv[]);
p
sid=getpid();
sigemptyset(&act.sa_mask);
act.sa_sigaction=new_op;//三参数信号处理函数
act.sa_flags=SA_SIGINFO;//信息传递开关
if(sigaction(sig,&act,NULL) < )
{
printf("install sigal error\n");
}
while()
{
sleep();
printf("wait for the signal\n");
sigqueue(pid,sig,mysigval);//向本进程发送信号,并传递附加信息
}
}
void new_op(int signum,siginfo_t *info,void *myact)//三参数信号处理函数的实现
{
int i;
for(i=; i<; i++)
{
printf("%c\n ",(*( (char*)((*info).si_ptr)+i))); }
printf("handle signal %d over;",signum);
}
- 消息队列
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
“消息队列”是 Microsoft 的消息处理技术,它在任何安装了 Microsoft Windows 的计算机组合中,为任何应用程序提供消息处理和消息队列功能,无论这些计算机是否在同一个网络上或者是否同时联机。
“消息队列网络”是能够相互间来回发送消息的任何一组计算机。网络中的不同计算机在确保消息顺利处理的过程中扮演不同的角色。它们中有些提供路由信息以确定如何发送消息,有些保存整个网络的重要信息,而有些只是发送和接收消息。
“消息队列”安装期间,管理员确定哪些服务器可以互相通信,并设置特定服务器的特殊角色。构成此“消息队列”网络的计算机称为“站点”,它们之间通过“站点链接”相互连接。每个站点链接都有一个关联的“开销”,它由管理员确定,指示了经过此站点链接传递消息的频率。
“消息队列”管理员还在网络中设置一台或多台作为“路由服务器”的计算机。路由服务器查看各站点链接的开销,确定经过多个站点传递消息的最快和最有效的方法,以此决定如何传递消息。
#include < stdio.h >
#include < stdlib.h >
#include < ctype.h >
#include < sys / ipc.h >
#include < sys / types.h >
#include < sys / msg.h > #define MAX_SEND_SIZE 80 struct mymsgbuf
{
long mtype;
char mtext[MAX_SEND_SIZE];
} ;
void send_message( int qid, struct mymsgbuf * qbuf, long type, char * text);
void read_message( int qid, struct mymsgbuf * qbuf, long type);
void remove_queue( int qid);
void change_queue_mode( int qid, char * mode);
void usage( void ); int main( int argc, char * argv[])
{
key_t key;
int msgqueue_id;
struct mymsgbuf qbuf; if ( == argc)
usage();
key = ftok( " . " , ' m ' );
if ((msgqueue_id = msgget(key,IPC_CREAT | )) ==- )
{
perror( " msgget " );
exit( );
}
switch (tolower(argv[ ][ ]))
{
case ' s ' :
send_message(msgqueue_id,( struct mymsgbuf * ) & qbuf,
atol(argv[ ]),argv[ ]);
break ;
case ' r ' :
read_message(msgqueue_id, & qbuf,atol(argv[ ]));
break ;
case ' d ' :
remove_queue(msgqueue_id);
break ;
case ' m ' :
change_queue_mode(msgqueue_id,argv[ ]);
break ;
default :
usage();
}
return ;
}
void send_message( int qid, struct mymsgbuf * qbuf, long type, char * text)
{
printf( " send a message /n " );
qbuf -> mtype = type;
strcpy(qbuf -> mtext,text);
if ((msgsnd(qid,( struct msgbuf * )qbuf,strlen(qbuf -> mtext) + , )) ==- )
{
perror( " msgsnd " );
exit( );
}
}
void read_message( int qid, struct mymsgbuf * qbuf, long type)
{
printf( " reading a message./n " );
qbuf -> mtype = type;
msgrcv(qid,( struct msgbuf * )qbuf,MAX_SEND_SIZE,type, );
printf( " Type: %1d Text: %s/n " ,qbuf -> mtype,qbuf -> mtext);
}
void remove_queue( int qid)
{
msgctl(qid,IPC_RMID, );
}
void change_queue_mode( int qid, char * mode)
{
struct msqid_ds myqueue_ds;
msgctl(qid,IPC_STAT, & myqueue_ds);
sscanf(mode, " %ho " , & myqueue_ds.msg_perm.mode);
msgctl(qid,IPC_SET, & myqueue_ds);
}
void usage( void )
{
fprintf(stderr, " msgtool -A utility for tinkering with msg queue/n " );
fprintf(stderr, " /nUSAGE:msgtool (s)end <type> <messagetext>/n " );
fprintf(stderr, " (r)ecv<type>/n " );
fprintf(stderr, " (d)elete/n " );
fprintf(stderr, " (m)ode<octal mode>/n " );
exit( );
}
2017-2018-1 20155317 IPC的更多相关文章
- MyEclips 2017/2018 (mac 版)安装与破解
MyEclips 2017/2018 (mac 版)安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclips ...
- MyEclipse 2017/2018 安装与破解 图文教程
SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...
- </2017><2018>
>>> Blog 随笔原始文档及源代码 -> github: https://github.com/StackLike/Python_Note >>> 统计信 ...
- 我的2017&2018
最近项目进入验收阶段,所以上班没那么忙碌了,但是怎么说呢,我可能天生是闲不住的主,觉得浑身不自在(我这样的人是不是特别不会享福),此处应该有个笑脸哈. 翻看了博客园好几个大牛写的技术文章,感慨大牛不愧 ...
- [2017 - 2018 ACL] 对话系统论文研究点整理
(论文编号及摘要见 [2017 ACL] 对话系统. [2018 ACL Long] 对话系统. 论文标题[]中最后的数字表示截止2019.1.21 google被引次数) 1. Domain Ada ...
- CorelDRAW X7 X8 2017 2018是什么关系?
从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...
- JetBrains 2017/2018全系列产品激活工具
可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...
- 【LOJ】#2349. 「JOI 2017/2018 决赛」团子制作
题解 有意思的一个dp,我们对G计数,发现如果不在同一条对角线上的G肯定不会互相影响,所以我们对于每一条对角线dp dp的方式是枚举这个G以什么方式放,横着还是竖着,还是不放 代码 #include ...
- 【LOJ】#2350. 「JOI 2017/2018 决赛」月票购买
题解 首先求一个最短路图出来,最短路图就是这条边在最短路上就保留,否则就不保留,注意最短路图是一个有向图,一条边被保留的条件是 dis(S,u) + val(u,v) = dis(v,T)我们需要求两 ...
随机推荐
- 结对作业——随机生成四则运算(Core 第7组)
结对作业 ——随机生成四则运算(core第7组) 吕佳玲 PB16060145 涂涵越 PB16060282 GITHUB地址 https://github.com/hytu99/homework_2 ...
- Oracle AP更新供应商
/*l_return_status:S l_msg_count:0 l_msg_data: l_vendor_id:133003 l_party_id:236055 */ DECLARE l_ ...
- 【Oracle】PL/SQL Developer使用技巧(持续更新中)
1.关键字自动大写 在sql命令窗口中输入SQL语句时,想要关键字自动大写,引人注目该怎么办呢? 一步设置就可以达成了.点击Tools->Preference->Editor,看到截图中这 ...
- Winform 多个窗口编辑同一条数据同步的实现
场景: 一个主窗口中,可以在列表(DataGridView)里选中一条记录编辑,打开一个编辑窗口(非模态窗口),编辑窗口保存后需要刷新父窗口,由于编辑窗口是非模态窗口,如果打开了多个窗口,并且都是编辑 ...
- 关于sys.dm_exec_requests
我知道SQL Server有很多视图和函数让我来了解SQL Server的运行状态.我还想知道SQL Server上关于来自用户或者应用的活动请求信息.怎么查询这些信息呢? SQL Server的动态 ...
- 设计标签选择器TitleSwitch
设计标签选择器TitleSwitch 效果如下: 源码如下: TitleSwitch.h 与 TitleSwitch.m // // TitleSwitch.h // TitleSwitch // / ...
- python3 django1.10 使用mysql服务器
python3中使用mysql报错ModuleNotFoundError: No module named 'MySQLdb' 原因是:在python2.x中用mysqldb,但是在python3.x ...
- 张高兴的 Windows 10 IoT 开发笔记:使用 MAX7219 驱动数码管
This is a Windows 10 IoT Core project on the Raspberry Pi 2/3, coded by C#. GitHub:https://github.co ...
- python3 装饰器全解
本章结构: 1.理解装饰器的前提准备 2.装饰器:无参/带参的被装饰函数,无参/带参的装饰函数 3.装饰器的缺点 4.python3的内置装饰器 5.本文参考 理解装饰器的前提:1.所有东西都是对象( ...
- JVM源码分析之堆外内存完全解读
JVM源码分析之堆外内存完全解读 寒泉子 2016-01-15 17:26:16 浏览6837 评论0 阿里技术协会 摘要: 概述 广义的堆外内存 说到堆外内存,那大家肯定想到堆内内存,这也是我们 ...