进程间通信
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
进程间通信:
与命名管道相比,消息队列的优势在于:
1、消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管
道的打开和关闭时可能产生的困难。
2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程
自己来提供同步方法。
3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,
只能默认地接收。
五种通讯方式总结
1.管道:速度慢,容量有限,只有父子进程能通讯
2.FIFO:任何进程间都能通讯,但速度慢
3.消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问
题
4.信号量:不能传递复杂消息,只能用来同步
5.共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一
个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了同一进程内的一块内存
底层通信库总结
.
.
Mmap用来进行进程间通信
TDoubleBuffer* G_TextLog(TDoubleBuffer::Create(0, 4 * 1024 * 1024, true));
即
TDoubleBuffer* G_TextLog=TDoubleBuffer::Create(0, 4 * 1024 * 1024, true)
即
TDoubleBuffer* TDoubleBuffer::Create(void* memobj, size_t memsize, bool isshared)
memobj = mmap(0, memsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
return new (memobj) TDoubleBuffer(memsize, isshared);
即
Create函数返回一个新的双缓冲对象,new()括号内制定分配的地址为memobj ,创建的对象是双缓冲对象。
这是一个共享内存对象。
主子进程间共用一个内存块。
于是,G_TextLog就是一个对象,存在的地址位于一个共享内存里。
细说mmap
mmap(0, memsize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
其中参数addr为描述符fd应该被映射到进程空间的起始地址,当指定为NULL时内核将自己去选择起始地址,无论addr是为NULL,函数返回值都是fd所映射到内存的起始地址;len是映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起,offset通常设置为0;
prot 参数指定共享内存的访问权限。
可取如下几个值的或:PROT_READ(可读), PROT_WRITE (可写), PROT_EXEC (可执行), PROT_NONE(不可访问),该值常设置为PROT_READ | PROT_WRITE 。
flags由以下几个常值指定:MAP_SHARED , MAP_PRIVATE , MAP_FIXED,其中,MAP_SHARED (变动是共享的,对共享内存的修改所有进程可见), MAP_PRIVATE(变动是私有的,对共享内存修改只对该进程可见)必选其一,而MAP_FIXED则不推荐使用。
1. mmap MAP_ANONYMOUS
在支持MAP_ANONYMOUS的系统上,直接用匿名共享内存即可,
mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED, -1, 0);
2. mmap /dev/zero
有些系统不支持匿名内存映射,则可以使用fopen打开/dev/zero文件,然后对该文件进行映射,可以同样达到匿名内存映射的效果。
fd=open("/dev/zero",O_RDWR);
if(fd==-1){
printf("open /dev/zero null\n");
return -1;
}
addr=mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(addr == NULL){
printf("mmap error\n");
return -1;
}
3. shmget shmat shmctl
shmget 是老式的system V 共享内存模式,很多系统都支持这种方法。
int id;
//得到一个共享内存标识符或创建一个共享内存对象并返回共享内存标识符
id = shmget(IPC_PRIVATE, shm->size, (SHM_R|SHM_W|IPC_CREAT));
if(id==-1){
perror("shmget:");
return -1;
}
//连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问
addr = shmat(id, NULL, 0);
if(addr == NULL){
perror("shmat:");
return -1;
}
//完成对共享内存的控制
if(shmctl(id, IPC_RMID, NULL)==-1){
perror("shmctl:");
return -1;
}。