2012-11-21 26 views
0

我需要創建一個共享內存段,以便我可以讓多個讀者和作者訪問它。我想我知道我在做什麼,只要信號量和讀者和作家去...任何人都可以幫助我在C中創建共享內存段

但我很無能,甚至如何創建一個共享內存段。我想讓這個細分受衆羣擁有20個結構。每個結構將保存一個名字,一個int和另一個int。

任何人都可以幫助我至少開始嗎?我絕望,我在網上閱讀的所有內容都讓我更加困惑。

編輯:好的,所以我做這樣的事情與STARTDATA開始

int memID = shmget(IPC_PRIVATE, sizeof(startData[0])*20, IPC_CREAT); 

爲結構的列保持初始化我的數據,我得到一個錯誤說 「分段錯誤(核心轉儲)」

+0

'人shmget'和'shmat' –

+0

在調用'shmget'或更高版本?你是否檢查對'shmget'的調用是否返回錯誤(如果是,則memID將爲-1,並且可以用'perror'打印錯誤)。 –

+1

我建議你先複製一個現有的例子,並根據需要進行修改。 http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/z2101586.htm – imreal

回答

1

獲取共享內存的現代方法是使用由Single UNIX Specification提供的API。這裏有兩個進程的例子 - 一個創建一個共享內存對象,並放入一些數據,另一個讀取它。

第一處理:

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

#define SHM_NAME "/test" 

typedef struct 
{ 
    int item; 
} DataItem; 

int main (void) 
{ 
    int smfd, i; 
    DataItem *smarr; 
    size_t size = 20*sizeof(DataItem); 

    // Create a shared memory object 
    smfd = shm_open(SHM_NAME, O_RDWR | O_CREAT, 0600); 
    // Resize to fit 
    ftruncate(smfd, size); 
    // Map the object 
    smarr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, smfd, 0); 

    // Put in some data 
    for (i = 0; i < 20; i++) 
     smarr[i].item = i; 

    printf("Press Enter to remove the shared memory object\n"); 
    getc(stdin); 

    // Unmap the object 
    munmap(smarr, size); 
    // Close the shared memory object handle 
    close(smfd); 
    // Remove the shared memory object 
    shm_unlink(SHM_NAME); 

    return 0; 
} 

過程產生與shm_open()共享存儲器對象。該對象的初始大小爲零,因此使用ftruncate()進行放大。然後使用mmap()將對象映射到進程的虛擬地址空間。這裏重要的是映射是可讀寫的(PROT_READ | PROT_WRITE),它是共享的(MAP_SHARED)。一旦完成映射,就可以將其作爲常規動態分配內存來訪問(事實上,在Linux上,glibc中的malloc()使用匿名內存映射進行更大的分配)。然後該進程將數據寫入數組並等待,直到按下Enter。然後它使用munmap()取消映射該對象,關閉其文件句柄並取消鏈接該對象與shm_unlink()

第二個過程:

#include <stdio.h> 
#include <sys/mman.h> 
#include <fcntl.h> 

#define SHM_NAME "/test" 

typedef struct 
{ 
    int item; 
} DataItem; 

int main (void) 
{ 
    int smfd, i; 
    DataItem *smarr; 
    size_t size = 20*sizeof(DataItem); 

    // Open the shared memory object 
    smfd = shm_open(SHM_NAME, O_RDONLY, 0600); 
    // Map the object 
    smarr = mmap(NULL, size, PROT_READ, MAP_SHARED, smfd, 0); 

    // Read the data 
    for (i = 0; i < 20; i++) 
     printf("Item %d is %d\n", i, smarr[i].item); 

    // Unmap the object 
    munmap(smarr, size); 
    // Close the shared memory object handle 
    close(smfd); 

    return 0; 
} 

這一個打開以進行讀訪問的共享存儲器對象只並且還存儲器映射它僅用於讀訪問。任何嘗試寫入smarr陣列的元素都會導致分段錯誤被傳遞。

編譯並運行第一個進程。然後在一個單獨的控制檯中運行第二個進程並觀察輸出。當第二個進程完成後,回到第一個進程並按Enter鍵清理共享內存塊。

有關更多信息,請參閱每個函數的手冊頁或SUS的memory management部分(最好在查看手冊頁時記錄這些函數的系統特定行爲)。

相關問題