簡體   English   中英

與mmap共享進程內存

[英]Share process memory with mmap

我有一個C程序,該程序在內存中生成大量數據,並且我需要在內存中共享此數據的一個特定部分,以便另一個進程可以對其進行讀取訪問。

我正在嘗試使用mmap來執行此操作,但是並沒有取得太大的成功。 這是我的代碼:

//Code above generates a pointer to the memory section I need to share, named addr

if (infoBlock->memory_size == 1073741824) { //This is the data block I need to share
   int err, fd;
   fd = open("/tmp/testOutput", (0_RDWR | 0_CREAT), S_IWUSR);
   if (fd < 0) {
         perror("Couldn't create output file\n");
         goto failedExit;
    }

    unsigned *p = mmap(addr, 1073741824, PROT_READ, (MAP_SHARED | MAP_FIXED), fd, 0);
    if (!p) {perror("mmap failed"); goto failedExit; }
    printf("p is now: %p\n", p); //This should point to the shared mapping
    printf("%u\n", *p); //Try to print out some data from the mapping

}

運行該程序后,我可以看到文件/ tmp / testOutput在那里,但是它的大小為0。我不確定這在內存映射中是否正常,因為從技術上講它不是文件。 而且,程序中的所有輸出都指向相同的內存地址。

我還可以看到/ proc / PID / maps中存在的內存映射,並帶有對/ tmp / testOutput的引用。

一切似乎都在運行,但是當涉及到對指針的解引用時,程序退出,我認為這是因為我做錯了映射,並且指針指向了它不應該指向的對象。

如果有人可以發現我在做什么錯,或者可以提供一些建議,將不勝感激。

謝謝!

您已經將與該文件關聯的存儲(或試圖)映射到了您的進程中,並且您堅持要將該文件映射到您已經用於其他用途的地址上(大概是addr被分配了)。

您沒有說p是否確實具有您所請求的地址,並且正如嫌疑人指出的那樣,您的錯誤檢查已損壞。

您的困惑:

事后,您不能將任意堆或其他進程內存頁面與文件關聯。 您必須在文件系統中分配它們,然后進行映射。 (盡管這並不是您所要求的,但有一種方法可以使用vmsplice將它們與UNIX管道關聯。)

請注意, MMAP_FIXED標志只會將與數據相關的頁面替換為您的數據所占用的頁面。 如果沒有該標志,則將忽略地址提示,並將映射放置在其他位置。

解決方案:

  1. 映射文件之前先將文件截短為所需大小(這將在文件系統中分配存儲空間)
  2. 映射然后填充
  3. 修復您的mmap錯誤檢查

如果您不能更改分配方案,則最好的管理方法是本地進程內存復制到映射中,在這種情況下,您最好將其write文件中。

理想的情況如下所示:

void *alloc_mmap(const char *filename, size_t length)
{
    int fd;
    fd = open(filename, (0_RDWR | 0_CREAT), S_IWUSR);
    if (fd < 0) {
        perror("Couldn't create output file\n");
        return NULL;
    }
    if (ftruncate(fd, length)) {
        perror("Couldn't grow output file\n");
        close(fd);
        return NULL;
    }

    void *p = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
    if (p == -1) {
        perror("mmap failed");
        close(fd);
        return NULL;
    }
    close(fd);
    return p;
}

// now you've allocated your memory, you can populate it and it will be
// reflected in the file

這是mmap手冊頁的摘錄。

   On  success,  mmap() returns a pointer to the mapped area.  On error, the value
   MAP_FAILED (that is, (void *) -1) is returned, and errno is set  appropriately.
   On  success,  munmap()  returns 0, on failure -1, and errno is set (probably to
   EINVAL).

應更改成功測試以測試mmap的-1返回值。 然后檢查errno值。 HTH。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM