POSIX支持多种IPC(进程间通信),包括共享内存和消息传递
这里探究其共享内存:
POSIX共享内存是使用内存映射文件组织的,将共享内存区域与文件关联。进程必须先使用shm_open()系统调用来创建一个共享内存对象:
shm_fd = shm_open(name,O_CREAT | O_RDRW,0666);
第一个参数指定共享内存对象的名字。需要访问这个共享内存的进程必须通过这个名字来引用该共享内存对象。随后的参数指定,如果还不存在共享内存对象,就会创建该对象(第二个参数),并且这个对象允许读和写( O RDRW),最后一个参数建立共享内存对象的目录权限。对于系统调用shm_open()的成功调用的话,会返回一个关于共享内存对象的int的文件描述符.
一旦创建了该对象,ftruncate()函数就被用于配置这个对象的大小,单位是比特:
const int SIZE = 4096;
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ftruncate(shm_fd,SIZE);
最后mmap()函数建立一个包含共享内存对象的内存映射文件。它还返回一个指向内存映射文件的指针,这用于访问共享内存对象。
下面代码使用生产者--消费者模型来实现的共享内存:
生产者:创建了一个共享内存对象,并想共享内存写入消息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const int SIZE = 4096;
const char *name = "OS";
const char *message0= "Studying ";
const char *message1= "Operating Systems ";
const char *message2= "Is Fun!";
int shm_fd;
void *ptr;
/* 创建共享内存*/
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/* 配置共享内存段的大小 */
ftruncate(shm_fd,SIZE);
/* 现在将共享内存段映射到进程的地址空间中。 */
ptr = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed\n");
return -1;
}
/**
* 现在写入消息到共享内存区域。
*ptr是指针
* 注意,在每次写入之后,我们必须增加ptr的以写入的字节数的值。.
*/
sprintf(ptr,"%s",message0);
ptr += strlen(message0);
sprintf(ptr,"%s",message1);
ptr += strlen(message1);
sprintf(ptr,"%s",message2);
ptr += strlen(message2);
return 0;
}
消费者:从共享内存对象中读取消息。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const char *name = "OS";
const int SIZE = 4096;
int shm_fd;
void *ptr;
int i;
/* 打开共享内存段 */
shm_fd = shm_open(name, O_RDONLY, 0666);
if (shm_fd == -1) {
printf("shared memory failed\n");
exit(-1);
}
/* 现在将共享内存段映射到进程的地址空间中 */
ptr = mmap(0,SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed\n");
exit(-1);
}
/* 现在从共享内存区域读取数据。 */
printf("%s",ptr);
/* remove the shared memory segment */
if (shm_unlink(name) == -1) {
printf("Error removing %s\n",name);
exit(-1);
}
return 0;
}