2012-08-28 105 views
2

我的程序有2個線程,我使用共享內存在兩者之間進行通信。調用shmat兩次

每個線程都有一個'init'方法。在init方法中,我調用'shmget'和'shmat'來獲取共享內存段並附加到局部變量。代碼的一部分是象下面這樣:

Thread 1 (which runs first): 

void init() { 
    this->segment_id = shmget(SAME_KEY,SAME_SIZE,IPC_CREAT|S_IRUSR|S_IWUSR|S_IROTH|S_IWOTH); 
    this->data  = shmat(this->segment_id,0,0); 
} 

Thread 2 (which runs after thread 1): 

void init() { 
    this->segment_id = shmget(SAME_KEY,SAME_SIZE,0); 
    this->data  = shmat(this->segment_id,0,0); 
} 

該程序正在運行,但它給出意想不到的結果。我擔心的是,在第二個線程中調用'shmat'可能會導致線程1中的'數據'無法訪問或出現某種故障。事實是,在線程1中,我可以訪問整個共享段,但在線程2中,我只能訪問前16個字節,所以我不知道發生了什麼。

這是否意味着每個共享內存段可以一次連接到1個位置? 可以兩次調用'shmat'使共享內存可以從不同的指針訪問嗎?

+1

「在線程2我只能訪問前16個字節」 - 當您嘗試訪問的第17個字節會發生什麼? SIGSEGV還是別的? –

+1

請注意,使用'shm_open()'然後'mmap()'的POSIX版本更易於使用。 – Ariel

+0

@SteveJessop:沒有錯誤發生,但是,當線程1將一堆數據寫入共享內存時,比如說1024字節,線程2可以讀取僅前16個字節的值,之後的所有字節都是零 – jondinham

回答

2

每個共享內存段可以一次連接到多個位置。可以調用'shmat'兩次以使共享內存可以從不同的指針訪問。

我懷疑在給定的例子中,你不能確定Thread1 :: init()是在Thread2 :: init()之前調用的,所以在Thread2中你正在訪問未創建的內存 - 所以這就是爲什麼觀察到問題。

這兩個調用都使用IPC_CREAT(當然沒有IPC_EXCL)。

manpage

+0

uhm,我發現我的錯誤,我在觸發線程2之前意外修改共享內存數據 – jondinham