2016-01-23 150 views
2

我正嘗試使用我在網上找到的示例和文檔創建共享內存區域。我的目標是IPC,所以我可以讓不同的流程相互交流。如何正確使用shm_open和mmap

這是我的C文件

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/mman.h> 
#include <errno.h> 

int main (int argc, char *argv[]) 
{ 

struct stat sb; 
off_t len; 
char *p; 
int fd; 

fd = shm_open("test", O_RDWR | O_CREAT); //,S_IRUSR | S_IWUSR); 

if (fd == -1) { 
    perror("open"); 
    return 1; 
} 

if (fstat(fd, &sb)==-1){ 
    perror("fstat"); 
    return 1; 
} 

/*if (!S_ISREG(sb.st_mode)){ 
    fprintf(stderr, "%s is not a file\n",fileName); 
    return 1; 
}*/ 

p = mmap(0, sb.st_size, PROT_WRITE, MAP_SHARED, fd, 0); 
if (p == MAP_FAILED){ 
    perror("mmap"); 


    return 1; 

} 

if (close(fd)==-1) { 
    perror("close"); 
    return 1; 

} 
for (len = 0; len < sb.st_size; len++) { 
    putchar(p[len]); 

} 

if (munmap(p, sb.st_size) == -1) { 
    perror("munmao"); 
    return 1; 
} 
fprintf(stderr,"\n"); 
return 0; 
} 

的問題是,我得到一個MMAP:無效的參數。我認爲fd有些問題,但不知道如何解決它,任何幫助將不勝感激。我使用最新的XCODE在優勝美地。

回答

3

您需要擴展共享內存映射的大小,至少在創建它時第一次。現在它的大小是0,並且mmap不會允許您進行零長度映射。

所以不是你的fstat()調用,執行例如: -

size_t len = 4096; 
if (ftruncate(fd, len) == -1) { 
    perror("ftruncate"); 
    return 1; 
} 

而且通過這個len針對mmap()。

+0

恐怕你的代碼不起作用,它給了我「ftruncate:無效的參數」 – Kilon

+1

好吧,它在Linux上工作正常,它似乎有關於shm_open/ftruncate的一些奇怪的行爲,請參閱http://stackoverflow.com/questions/25502229/ftruncate-not-working-on-posix-shared-memory-in-mac-os-x(即,你已經運行了你的程序幾次了,所以你需要首先刪除該段。 shm_open調用需要一個你註釋掉的參數,hm_open(「test」,O_RDWR | O_CREAT,S_IRUSR | S_IWUSR);); – nos

+0

謝謝你的幫助。爲了測試的目的,我已經將這些部分評論過了,我甚至試過將它們包括在內。我想我會堅持使用open並禁止使用shm_open,因爲我決定將我的共享內存作爲msync的備份存儲到文件中。 – Kilon

-3

您的addr參數設置爲0,這可能是保留的。您的意思是使用NULL?這與0不同。

+0

Downvote同樣來自我,因爲您需要在提供答案之前查看mmap的工作方式。 0是mmap最常用的地址,如果地址被佔用,內核將會找到一個免費的地址。 – Kilon

相關問題