2008-12-23 25 views
5

我仍然試圖調試一個非常狡猾的內存損壞問題。我遇到了一段代碼,它在一個線程上分配內存,並在另一個線程上刪除它。跨線程的內存分配和釋放

我有一個模糊的感覺,這是錯誤的,但我不知道爲什麼。線程共享進程內存,對這些結構的訪問受到互斥體的保護,所以我認爲一切都會起作用。但是,有沒有我沒有看到的危險?

回答

5

爲在@monjardin另一個答覆中指出,沒有什麼內在的錯誤你正在嘗試做的。

作爲一個額外的想法,你沒有提到你遇到這個問題的平臺等,但如果多線程對你和/或你正在處理的這個應用程序是新的,你想確保您正在使用的標準支持庫是這些庫的線程安全版本。在許多環境/平臺中,開發人員可以使用支持庫的單線程和多線程版本。如果您正在使用線程,但是與單個線程版本的庫鏈接,則可能會發生很多不好的事情。例如,在的單線程支持庫中malloc()free()它不會具有堆的互斥保護(作爲優化)。該庫的多線程版本將爲堆管理器添加互斥保護,以支持一次處理多個堆的線程。 (這只是一個例子)。

0

危險之處在於多線程代碼更難編寫。但是,如果程序是正確的,那麼應該沒有問題。這可能是producer/consumer模式,其中生產線程分配放置在由消費線程釋放的synchronized queue中的內存。

0

只要內存的分配和釋放得到了適當的保護您還可以確保只有在它們處於同一個互斥鎖時才能訪問這些結構,我不能真正看到這是一個問題。請注意,這適用於讀取和寫入訪問,不僅用於寫入訪問,因爲您需要確保結構保持在某人從其讀取數據的位置。

是否有機會嘗試在互斥保護之外訪問這些數據結構?或者更糟糕的是,這些結構中的某些可能會成爲C++對象生命週期考慮的犧牲品(比如,它們因爲通過boost :: shared_ptrs引用而最後被shared_ptr剛剛退出了建築物而被銷燬了?)

你是否100%肯定它是內存損壞?另一個看起來非常相似的錯誤是,當一些代碼持有一個引用時,它不應該被引用的對象由於內存重新分配而被移動,這不是一個奇怪的場景因爲加入一個新元素的矢量可以觸發(只是舉一個例子)。

+0

只要一個線程一次「擁有」指向對象的指針,訪問對象時就沒有嚴格的互斥保護要求。例如,在另一個答案中提到的生產者/消費者模型 – 2008-12-23 21:41:47

1

不,這很好,尤其是在使用CreateThread的Wi​​ndows編程中,您可以在堆中分配參數,並將參數作爲void *參數傳遞給CreateThread。最簡單的做法是讓被調用的線程在完成它們時刪除它的參數。但是,如果你有內存損壞問題,並且你擔心有一個線程刪除另一個創建的內存,也許你應該考慮是否存在一個雙重刪除發生,說如果現在負責清理分配的內容的傳輸內存不清楚,或許這兩個呼叫和被叫部分都在做呢?

1

請記住,內存管理器本身也必須是線程安全的,不僅僅是您使用內存。檢查你的平臺文檔。