我正在尝试允许两个不同的进程通过使用内存映射相同的文件进行通信。但是,我遇到了一些问题。我有一种感觉,这与我使用open()调用并将我的文件描述符传递给mmap的方式有关。
这是我的代码,你能看到它有什么问题吗?
对象1的代码:
16 FILE* temp = fopen(theSharedFileName, "w");
17 fseek(temp, fileSize-1, SEEK_SET);
18 fprintf(temp, "0"); // make the file a certain size
19 fseek(temp, 0, SEEK_CUR);
20
21 int sharedFileName = fileno(temp);
...
31 sharedArea = (MyStruct*)mmap(0, fileSize,
32 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, sharedFileName, 0);
我使用“w”文件模式,因为对象1只会被制作一次,我希望它能重置以前存在的任何数据。
对象2的代码:
130 FILE* tempFile = fopen(sharedFileName, "a");
131 int theFile = fileno(tempFile);
...
135 sharedArea = (MyStruct*)mmap(NULL, fileSize,
136 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, theFile, 0);
答案 0 :(得分:24)
一些问题:
PROT_READ | PROT_WRITE | PROT_EXEC
传递给mmap(),因此您违反了此限制。这也突出了为什么你不应该将高级I / O与内存映射混合:你如何保证fopen(...,"w")
将使用正确的标志打开文件?这应该是C库的“实现细节”。如果要对具有读写权限的文件进行内存映射,则应使用低级open(theSharedFileName, O_RDWR)
打开该文件。PROT_WRITE
和PROT_EXEC
。它不是便携式和,这是一种安全风险。阅读W^X和executable space protection。答案 1 :(得分:2)
答案 2 :(得分:1)
正如其他人所说,不要使用fopen()和朋友。
您遇到的部分问题可能是由于fprintf()可能具有流缓冲区,因此它实际上可能无法更改文件,因此在预期时对其他进程可见。你可以添加一个fflush(),但read()和write()不做任何应用程序级缓冲,这是它们更合适的部分原因。