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 ; }

- 管道

—管道是一种半双工的通信方式
—数据只能单向流动,而且只能在具有共同祖先的进程间使用。 所谓半双工的模式(以下是我的理解): 形象来说类似一个单刀双掷开关,有两个选择,但是二者是互斥的,当选择了一方另一方就失效。 而对于此处的管道,可以把它想成是管道的一端,一次只能调用一种功能读入或者写入,二者也是互斥的。 同时对应的fd[0]与fd[1]其实是一个类似一个临界区的资源,一次只能由一个进程使用一种功能,所以使用时要注意分配读和写的功能。
父进程创建管道和两个子进程p1和p2
¢2.子进程p1打开给定文件(如果没有,则创建文件),并向文件中写数据,写完关闭文件,然后向管道写入一条消息“ok",目的是通知进程p2可以读取文件内容了。
¢3.子进程p2通过管道读取消息,如果消息是“ok”,则打开文件,读取文件内容,并将其输出到屏幕上,关闭文件.

#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的更多相关文章

  1. MyEclips 2017/2018 (mac 版)安装与破解

    MyEclips 2017/2018 (mac 版)安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclips ...

  2. MyEclipse 2017/2018 安装与破解 图文教程

    SSM 框架-02-MyEclipse 2017/2018 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEc ...

  3. </2017><2018>

    >>> Blog 随笔原始文档及源代码 -> github: https://github.com/StackLike/Python_Note >>> 统计信 ...

  4. 我的2017&2018

    最近项目进入验收阶段,所以上班没那么忙碌了,但是怎么说呢,我可能天生是闲不住的主,觉得浑身不自在(我这样的人是不是特别不会享福),此处应该有个笑脸哈. 翻看了博客园好几个大牛写的技术文章,感慨大牛不愧 ...

  5. [2017 - 2018 ACL] 对话系统论文研究点整理

    (论文编号及摘要见 [2017 ACL] 对话系统. [2018 ACL Long] 对话系统. 论文标题[]中最后的数字表示截止2019.1.21 google被引次数) 1. Domain Ada ...

  6. CorelDRAW X7 X8 2017 2018是什么关系?

    从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼,所以有时候很多朋友对于软件版本,经常会傻傻分不清,还有人认为X8版本比2017版本高,究竟为什么会 ...

  7. JetBrains 2017/2018全系列产品激活工具

    可谓是工欲善其事,必先利其器,相信作为优秀开发工程师的你都想拥有一套快捷高效的编码工具,而JetBrains这家公司的产品,不管是那种编程语言,其开发工具确实让开发者们着迷,JetBrains的产品博 ...

  8. 【LOJ】#2349. 「JOI 2017/2018 决赛」团子制作

    题解 有意思的一个dp,我们对G计数,发现如果不在同一条对角线上的G肯定不会互相影响,所以我们对于每一条对角线dp dp的方式是枚举这个G以什么方式放,横着还是竖着,还是不放 代码 #include ...

  9. 【LOJ】#2350. 「JOI 2017/2018 决赛」月票购买

    题解 首先求一个最短路图出来,最短路图就是这条边在最短路上就保留,否则就不保留,注意最短路图是一个有向图,一条边被保留的条件是 dis(S,u) + val(u,v) = dis(v,T)我们需要求两 ...

随机推荐

  1. Linux内核态和用户态

    两张图说明Linux内核态和用户态之间的关系

  2. Python初学者第二十四天 函数进阶(3)生成器

    24day 1.列表生成式: 循环模式:[变量(加工后的变量) for 变量 in iterable] print([i for i in range(0,101,2)]) [1,4,9,16,25, ...

  3. 铁乐学python_day23_面向对象进阶1_反射

    铁乐学python_day23_面向对象进阶1_反射 以下内容大部分摘自博客http://www.cnblogs.com/Eva-J/ isinstance()和issubclass() 两者的返回值 ...

  4. n = 3 , while n , continue

  5. 重复文件查找工具:Duplicate Cleaner V4.11绿色免费版

    Duplicate Cleaner 是一款可以帮助你在你的计算机上找到并且快速查找出重复文件并标记出不同的颜色,让你轻松查阅处理.你可以立即搜索多个文件夹结构并且设置识别副本文件的标准.你可以选择使用 ...

  6. SDN 第一次作业

    你会选择作 网络编程 方向的程序员吗?为什么? 答: 可能会选择吧.看了那篇文章感觉网络编程的程序员和其他的程序员都并不简单,网络编程的程序员可能更要对网络的知识更加了解.我现在也有机会能接触网络方向 ...

  7. Weblogic web应用中获取文件的绝对路径

    注意点: 1. file必须在/下,或者/WEB-INF/,不能在classes下 2. weblogic中进行如下配置,以获取绝对路径: <wls:container-descriptor&g ...

  8. loj6119 「2017 山东二轮集训 Day7」国王

    题目描述 在某个神奇的大陆上,有一个国家,这片大陆的所有城市间的道路网可以看做是一棵树,每个城市要么是工业城市,要么是农业城市,这个国家的人认为一条路径是 exciting 的,当且仅当这条路径上的工 ...

  9. 在jupyter notebook中运行R语言

    要想在jupyter notebook中运行R语言其实非常简单,按顺序安装下面扩展包即可: install.package('repr','IRdisplay','evaluate','crayon' ...

  10. KVOController原理解析

    1.使用类似动态代理的模式和消息派发中枢模式实现整个架构: 2.使用NSMapTable和NSHashTable进行切面信息的增删查维护:主要用于去重和查看是否存在. 实现方式 消息流 KVOCont ...