首页 > 代码库 > 进程通信-

进程通信-

1.消息队列的严重缺陷

消息队列使用的数据缓冲区是全局共享的,有容量限制。如果消息队列的消费方,也就是读取并移除数据块的程序异常(例如退出后没有再运行起来),不再移除数据块,那么随着写入程序的不断写入数据,缓冲区会溢出。一旦缓冲区溢出,那么任何写消息队列的程序都无法正常写入数据块。如果移除消息队列数据块的程序出现问题,不仅会影响本系统业务,还会影响到其他使用消息队列的业务程序的正常运行,数据通信发生阻塞。因此,在一般的企业软件系统里,不提倡使用消息队列机制。

2.共享内存

共享内存非常适合于多个线程共享大容量的数据。还有一个特点,就是建立的内存不会因为建立的程序退出而消失,一直驻留再内存里,直到机器重启才消失。共享内存和文件一样有操作权限,如果没有读取或写入权限,是无法看到其他用户甚至是自己建立的共享内存的,除非是root用户。

命令ipcs可以用来查看存在的共享内存,命令ipcrm可以删除给定的共享内存。删除正在使用的共享内存,可能会导致存取他的程序工作异常,所以删除前,要谨慎确认。

对共享内存的操作有以下几种:

shmget() 建立共享内存或获取共享内存句柄

shmat()把共享内存映射到进程的内存,映射的内存和共享内存的数据完全一致,可以直接读写。

shmdt()取消共享内存到内存的映射。在映射共享内存时,需要用信号量机制排斥其他进程或线程对此共享内存的操作,完成操作后,在取消映射后,用信号量解锁以便其他进程或线程操作此共享内存。

shmctl()可以读取或设定共享内存的一些特性,删除共享内存也可以用这个函数完成。

共享内存里可以存放各种数据量,但是不要存放指针,因为一个进程里的指针对另外的进程没有任何意义。共享内存里存放的整数,注意对齐格式。

3.文件映射

共享的是文件,再建立进程和操作系统重启后都不会消失。

文件映射操作:

open()打开文件获得文件句柄

mmap()文件内容映射到进程内存,映射的内存和文件的内容完全一致,可以直接读写。

msync()把内存修改的内容同步回文件

munmap()取消文件到内存的映射

close()关闭文件

文件映射和共享内存的映射相比,其数据映射到内存时,可以选定偏移量和要映射的数据块的大小,数据块的大小一般会自动对齐为内存页的大小的整数倍。页的大小可以用函数sysconf(_SC_PAGESIZE或_SC_PAGE_SIZE)

4信号量

操作:

semget()建立或打开一组信号量,如果是建立信号量,用函数semctl()初始化信号量的值,用semop()独占锁定信号量或解锁信号量,操作可以选定此组信号量的一个或多个或全部。当不再使用信号量时,可以用函数semctl()删除信号量。

 

进程通信-