它将分配 ByteSize 字节的内存,在该情况下,一般为大小适中的 512 字节。memwriter 和 memreader 程序都只从共享内存中获取数据,而不是从备份文件。系统将负责共享内存和备份文件之间数据的同步。
接着 memwriter 调用 mmap 函数:
caddr_t memptr = mmap(NULL, /* let system pick where to put segment */ ByteSize, /* how many bytes */ PROT_READ | PROT_WRITE, /* access protections */ MAP_SHARED, /* mapping visible to other processes */ fd, /* file descriptor */ 0); /* offset: start at 1st byte */
来获得共享内存的指针。(memreader 也做一次类似的调用。) 指针类型 caddr_t 以 c 开头,它代表 calloc ,而这是动态初始化分配的内存为 0 的一个系统函数。memwriter 通过库函数 strcpy (字符串复制)来获取后续写操作的 memptr 。
到现在为止,memwriter 已经准备好进行写操作了,但首先它要创建一个信号量来确保共享内存的排斥性。假如 memwriter 正在执行写操作而同时 memreader 在执行读操作,则有可能出现竞争条件。假如调用 sem_open 成功了:
sem_t* semptr = sem_open(SemaphoreName, /* name */ O_CREAT, /* create the semaphore */ AccessPerms, /* protection perms */ 0); /* initial value */
那么,接着写操作便可以执行。上面的 SemaphoreName (任意一个唯一的非空名称)用来在 memwriter 和 memreader 识别信号量。初始值 0 将会传递给信号量的创建者,在这个例子中指的是 memwriter 赋予它执行写操作的权利。
在写操作完成后,memwriter* 通过调用 sem_post` 函数将信号量的值增加到 1:
if (sem_post(semptr) < 0) ..
增加信号了将释放互斥锁,使得 memreader 可以执行它的读操作。为了更好地测量,memwriter 也将从它自己的地址空间中取消映射,
munmap(memptr, ByteSize); /* unmap the storage *
这将使得 memwriter 不能进一步地访问共享内存。
示例 4. memreader 进程的源代码
/** Compilation: gcc -o memreader memreader.c -lrt -lpthread **/ #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <semaphore.h> #include <string.h> #include "shmem.h" -
void report_and_exit(const char* msg) { [perror][4](msg); [exit][5](-1); } -
int main() { int fd = shm_open(BackingFile, O_RDWR, AccessPerms); /* empty to begin */ if (fd < 0) report_and_exit("Can't get file descriptor..."); -
/* get a pointer to memory */ caddr_t memptr = mmap(NULL, /* let system pick where to put segment */ ByteSize, /* how many bytes */ PROT_READ | PROT_WRITE, /* access protections */ MAP_SHARED, /* mapping visible to other processes */ fd, /* file descriptor */ 0); /* offset: start at 1st byte */ if ((caddr_t) -1 == memptr) report_and_exit("Can't access segment..."); -
/* create a semaphore for mutual exclusion */ sem_t* semptr = sem_open(SemaphoreName, /* name */ O_CREAT, /* create the semaphore */ AccessPerms, /* protection perms */ 0); /* initial value */ if (semptr == (void*) -1) report_and_exit("sem_open"); -
/* use semaphore as a mutex (lock) by waiting for writer to increment it */ if (!sem_wait(semptr)) { /* wait until semaphore != 0 */ int i; for (i = 0; i < [strlen][6](MemContents); i++) write(STDOUT_FILENO, memptr + i, 1); /* one byte at a time */ sem_post(semptr); } -
/* cleanup */ munmap(memptr, ByteSize); close(fd); sem_close(semptr); unlink(BackingFile); return 0; }
(编辑:ASP站长网)
|