void *mmap(void *addr, size_t len, int prot,
int flags,int fildes, off_t off);
- addr:用來告知從哪個記憶體位址開始映射,不過通常是擺 NULL,直接給作業系統決定,否則還要考慮對齊問題(alignment)
- len:映射的大小
- prot:對此記憶體的操作限制,如:PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE
- flags:對此記憶體的存取方式,如:MAP_SHARED、MAP_PRIVATE、MAP_FIXED,使用 MAP_SHARED 時,如果某一個行程有對 mmap 的記憶體做修改,那其他同樣有做 mmap 的行程會看到相同結果。(對同一個檔案)
- fildes:open file 所得到的 fd。
- off:指定檔案從哪裡開始對映
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define FILE_LENGTH 0x400 /* 1024 */
int main(int argc, char *argv[])
{
int fd;
void *map_memory;
if(argc < 2) {
printf("Usage: ./a.out <string>\n");
return 1;
}
/*
* Open a file to be mapped.
* S_IRUSR: read permission, owner
* S_IWUSR: write permission, owner
*/
fd = open("/tmp/shared_file", O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR);
lseek(fd, FILE_LENGTH-1, SEEK_SET);
write(fd, "", 1);
lseek(fd, 0, SEEK_SET);
/* Create map memory. */
map_memory = mmap(0, FILE_LENGTH,
PROT_WRITE, MAP_SHARED,
fd, 0);
close(fd);
/* Write to mapped memory. */
if(strlen(argv[1]) < FILE_LENGTH)
sprintf((char*)map_memory, "%s", argv[1]);
munmap(map_memory, FILE_LENGTH);
return 0;
}
這樣的作法還是可以將內容寫入檔案,而且速度比單純寫入檔案還要快,但似乎 mmap有大小的限制,因為我設定到 0x40000000,程式執行完後,系統變得怪怪的 =.=?。以下是該測試程式的 VMA 區段,位於 /proc/xxxx/maps,其中 xxxx 是 process id,可以在執行程式時輸入 &,如:./mmaptest input_string &。08048000-08049000 r-xp 00000000 08:06 606289 /home/linly/Sample/mmap_write
...
b7df2000-b7f4a000 r-xp 00000000 08:06 1497227 /lib/tls/i686/cmov/libc-2.8.90.so
...
b7f61000-b7f62000 -w-s 00000000 08:06 686791 /tmp/shared_file
...
b7f80000-b7f81000 rw-p 0001b000 08:06 1479875 /lib/ld-2.8.90.so
bff6c000-bff81000 rw-p bffeb000 00:00 0 [stack]

沒有留言:
張貼留言