2011-08-30 52 views
12

我想兩個進程之間的通信之間的通信。我試圖在一個進程中將數據(如姓名,電話號碼,地址)保存到共享內存中,並試圖通過其他進程打印該數據。如何使用共享內存兩種工藝

process1.c

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
int main() 
{ 
    int segment_id; 
    char* shared_memory[3]; 
    int segment_size; 
    key_t shm_key; 
    int i=0; 
    const int shared_segment_size = 0x6400; 
    /* Allocate a shared memory segment. */ 
    segment_id = shmget (shm_key, shared_segment_size, 
      IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); 
    /* Attach the shared memory segment. */ 
    shared_memory[3] = (char*) shmat (segment_id, 0, 0); 
    printf ("shared memory attached at address %p\n", shared_memory); 
    /* Write a string to the shared memory segment. */ 
    sprintf(shared_memory[i], "maddy \n"); 
    sprintf(shared_memory[i+1], "73453916\n"); 
    sprintf(shared_memory[i+2], "america\n"); 

    /*calling the other process*/ 
    system("./process2"); 

    /* Detach the shared memory segment. */ 
    shmdt (shared_memory); 
    /* Deallocate the shared memory segment.*/ 
    shmctl (segment_id, IPC_RMID, 0); 

    return 0; 
} 

process2.c

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
int main() 
{ 
    int segment_id; 
    char* shared_memory[3]; 
    int segment_size; 
    int i=0; 
    key_t shm_key; 
    const int shared_segment_size = 0x6400; 
    /* Allocate a shared memory segment. */ 
    segment_id = shmget (shm_key, shared_segment_size, 
       S_IRUSR | S_IWUSR); 
    /* Attach the shared memory segment. */ 
    shared_memory[3] = (char*) shmat (segment_id, 0, 0); 
    printf ("shared memory22 attached at address %p\n", shared_memory); 
    printf ("name=%s\n", shared_memory[i]); 
    printf ("%s\n", shared_memory[i+1]); 
    printf ("%s\n", shared_memory[i+2]); 
    /* Detach the shared memory segment. */ 
    shmdt (shared_memory); 
    return 0; 
} 

但我沒有得到期望的輸出。 這是我得到的輸出是:

shared memory attached at address 0x7fff0fd2d460 
Segmentation fault 

任何人都可以請幫助我。這是初始化shared_memory[3]的正確方法。

謝謝。

回答

14
char* shared_memory[3]; 
... 
shared_memory[3] = (char*) shmat (segment_id, 0, 0); 

您聲明shared_memory爲可容納三個指針爲char數組,但你實際做的是寫指針一個數組結束落後的地方。由於沒有告訴記憶是否用於其他用途,接下來發生的情況通常是不可預測的。

當您嘗試使用shared_memory[0]shared_memory[2]中的指針時,事情總會變得很糟糕,因爲這些指針從未初始化過。他們充滿了從堆棧中無意義的垃圾 - 因此分段錯誤。

看來,在一般情況下,你是失敗的陣列及其元件之間進行區分。在您嘗試使用共享內存IPC之前,您應該先使用對代碼和指針在順序代碼中更加適應。共享內存

注意是做IPC在那裏的更容易獲得,錯誤的方法之一。除非你有剛性效率的制約,打算交換數據的很多,它更容易與管道,命名管道,或插座工作。

+0

謝謝亨寧。 – maddy

0

你應該保留足夠的共享內存交換數據。即使使用共享指針,進程也不應該訪問其他內存。請記住,只有在運行時寫入的原始數據是共享的,沒有類型檢查或任何其他元數據傳遞。如果數據允許使用固定大小的數組,則可以使用通用結構來更輕鬆地訪問數據。否則,您將不得不在這些進程之間手動封送數據。

11

其他兩個答案告訴你,什麼是錯的,但我想給你一個可運行的代碼。你可以修改它來傳遞任何東西,原則是你需要保存傳遞​​給對方的每個元素的長度。

//write.c

#include <stdio.h> 
#include <string.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

int main() 
{ 
    key_t shm_key = 6166529; 
    const int shm_size = 1024; 

    int shm_id; 
    char* shmaddr, *ptr; 
    int next[2]; 

    printf ("writer started.\n"); 

    /* Allocate a shared memory segment. */ 
    shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR); 

    /* Attach the shared memory segment. */ 
    shmaddr = (char*) shmat (shm_id, 0, 0); 

    printf ("shared memory attached at address %p\n", shmaddr); 

    /* Start to write data. */ 
    ptr = shmaddr + sizeof (next); 
    next[0] = sprintf (ptr, "mandy") + 1; 
    ptr += next[0]; 
    next[1] = sprintf (ptr, "73453916") + 1; 
    ptr += next[1]; 
    sprintf (ptr, "amarica"); 
    memcpy(shmaddr, &next, sizeof (next)); 
    printf ("writer ended.\n"); 

    /*calling the other process*/ 
    system("./read"); 

    /* Detach the shared memory segment. */ 
    shmdt (shmaddr); 
    /* Deallocate the shared memory segment.*/ 
    shmctl (shm_id, IPC_RMID, 0); 

    return 0; 
} 

//讀取。ç

#include <stdio.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 

int main() 
{ 
    key_t shm_key = 6166529; 
    const int shm_size = 1024; 

    int shm_id; 
    char* shmaddr, *ptr; 
    char* shared_memory[3]; 
    int *p; 

    /* Allocate a shared memory segment. */ 
    shm_id = shmget (shm_key, shm_size, IPC_CREAT | S_IRUSR | S_IWUSR); 

    /* Attach the shared memory segment. */ 
    shmaddr = (char*) shmat (shm_id, 0, 0); 

    printf ("shared memory attached at address %p\n", shmaddr); 

    /* Start to read data. */ 
    p = (int *)shmaddr; 
    ptr = shmaddr + sizeof (int) * 2; 
    shared_memory[0] = ptr; 
    ptr += *p++; 
    shared_memory[1] = ptr; 
    ptr += *p; 
    shared_memory[2] = ptr; 
    printf ("0=%s\n", shared_memory[0]); 
    printf ("1=%s\n", shared_memory[1]); 
    printf ("2=%s\n", shared_memory[2]); 

    /* Detach the shared memory segment. */ 
    shmdt (shmaddr); 
    return 0; 
} 

//運行結果:

> [lex:shm]$ ./write 
> writer started. 
> shared memory attached at address 0x7fa20103b000 
> writer ended. 
> shared memory attached at address0x7fd85e2eb000 
> 0=mandy 
> 1=73453916 
> 2=amarica 
+0

在read.c期間不會調用IPC_CREAT創建一組全新的共享內存,而不是獲取現有的共享內存? – Sherd