2009-12-26 49 views
2

我想在兩個進程之間創建共享內存。我用fork()。一個孩子試圖改變這個共享記憶,母親創造另一個孩子,所以新孩子試圖改變相同的記憶。這是我在C編程中的代碼。 (ubuntu)用於分叉的共享內存

mylist ch=NUL; 
f=fork(); 
if(!f){ 
     pba=shmget(KEYSHM,sizeof(char),0); /*created shared memory*/ 
     ch=(mylist *) shmat(pba,0,0); 
     ch->name=ugur; 
     ch->surname=cedric; 
...do something... 
} 
else{ 
     if(ch) 
     printf("this is top of mylist %s"ch->name); 
.......do something 
} 

它從不寫ch-> name。爲什麼?我創建了一個共享內存。爲什麼父進程無法讀取?

回答

3

你有一個競爭條件,如果父母在孩子面前跑步,你試圖訪問ch->在孩子已經放置什麼東西之前該怎麼辦?

你也只分配1個字節(sizeof(char)),但你試圖把它當作一個指向結構的指針 - 你需要爲mylist分配足夠的空間 - 除非你這樣做的更加錯誤。你需要IPC_CREAT標誌來在某處進行調試。

1

如果第一次運行父進程無法訪問ch->name,因爲ch->name=ugur;還沒有運行。我推薦看到這個tutorial的共享內存和這pdf file
一個解決方案,我認爲在fork()之前獲得共享內存,並將其用於兒童和父母。

1

你寫代碼的方式是,ch將指向一些共享內存,但ch本身(即指針)不共享。因爲ch的賦值只發生在子級中,所以父級將繼續將ch看作NULL。

您有兩種方法來解決這個問題:

  1. 設置之前叉共享內存。
  2. 讓父母和孩子都打開相同的共享內存。

在處理共享內存中的記錄時,需要確保該記錄的所有數據都存在共享內存中。例如,在此代碼中:

ch->name=ugur; 
    ch->surname=cedric; 

看來,mylist :: name是一個char *。如果ch指向共享內存中的記錄,這隻會將指向名稱的指針放在共享內存中。除非您採取特定步驟將這些字符串放入共享內存中,否則它們將存儲在正常內存中,並且可能無法被其他程序訪問。

5

要共享內存,父級和子級必須訪問相同的共享內存。

你有兩個選擇,簡單的和困難:

  • 創建和分叉之前附加到共享內存。父母和孩子都可以自動訪問相同的共享內存。

  • 先分叉,然後父母和孩子必須分別附加到共享內存。一旦這些進程分叉了,它們就不再共享內存了,特別是,在父進程中不能訪問在子進程中分配的任何內容。

您需要分配多於1個字符的共享內存來存儲有用的字符串,例如名稱。

0

如果我在分叉之前創建並附加共享內存,那麼我無法檢查共享內存是否爲NULL。它在附加時啓動。

0

您還使用了0作爲標誌,它指定訪問權限等內容,以及是否應創建共享內存段。換句話說,你沒有給自己讀或寫訪問權限,也沒有指定要創建的段,如果它尚不存在。