2011-08-26 95 views
0

我的代碼有一個線程連續處理由其他線程排隊的對象。排隊的對象是在函數中使用「new」創建的,該函數將在處理對象時完成。我沒有問題,但刪除對象。 我應該不刪除對象嗎?也許改變傳遞/創建這個對象的方式?刪除現有對象時出現分段錯誤

Object* myQueue[10]; 

function() { 
    Object* myobject = new Object(); 
    queueObject(myobject); 
} 

queueObject(Object* object) { 
    myQueue[index_x] = object; 
    sem_post(&mySemaphore); 
} 


//// Thread 1 
function(); 
... 

//// Thread 2 
handleObjects() { 
    while(true) { 
     sem_wait(&mySemaphore); 
     // handle myQueue[index_x] 
     delete myQueue[index_x]; ---> this produces Segmentation Fault 
    } 
} 

(index_x的治療不發佈到縮寫)

+4

「index_x的處理」可能是重要的一部分;)我沒有看到你在這裏發佈的內容的任何錯誤。一些可能性:刪除對象後,您可能不會從myQueue中刪除對象(或者不要再次操作index_x,以免再次刪除對象); index_x可能超出範圍; etc. –

+0

我可以在刪除它之前檢查它的屬性,所以索引是正確的 – funkadelic

+0

刪除它之前它是有效的事實表明另一個線程在刪除操作的地址被計算之前使index_x無效... –

回答

1

添加刪除

if (myQueue[index] != 0) { 
     delete myQueue[index]; 
     myQueue[index] = 0; 
} else { 
     for diagnosis print large warning here - something is confused 
} 

這種通過相同指數捕捉雙缺失周圍的一些檢查。但是還有其他幾種可能發生崩潰的方式。捕捉那些將需要其他行動。

考慮:

  1. 有競爭條件的可能性?兩個線程是否可以嘗試刪除相同的索引?你需要添加任何同步嗎?
  2. 是否有可能將同一個對象以不同的索引添加到數組中兩次?在極端情況下,我可能會添加代碼來驗證該項目在添加之前不在數組中。
+0

如果有涉及索引的爭用條件仍然會導致意外的行爲,並最終可能崩潰(將錯誤的索引歸零會導致內存泄漏,並且/或者在稍後得到雙重結構)。 –

+0

關於種族情況:是的,我列出了一些我們可以得到症狀的方法,空檢查並沒有解決所有問題。我澄清了我的意圖。排除錯誤的索引是問題最少的問題:如果索引錯誤,您剛纔刪除了錯誤的東西。 – djna

+0

問題在於析構函數中......謝謝! – funkadelic

1

我猜你有一個競爭條件。你用什麼防止index_x被兩個線程修改的同步機制?

工作線程通常應該調用sem_wait,修改關鍵數據,然後調用sem_post。沒有看到你是如何使用index_x我不能提供100%準確的示例代碼,但它看起來像以下:

queueObject(Object* object) { 
    sem_wait(&mySemaphore); 
    myQueue[index_x++] = object; 
    sem_post(&mySemaphore); 
} 

handleObjects() { 
    while(true) { 
     sem_wait(&mySemaphore); 
     // handle myQueue[index_x] 
     delete myQueue[--index_x] 
     sem_post(&mySemaphore); 
    } 
} 

目前,它看起來你有什麼可以阻止index_x由兩個被修改線程,這可能會導致index_x做些令人毛骨悚然的事情(無法增加或減少最常見的東西)。 Here是一篇維基百科文章,用於解釋可能出現的問題。

+0

我發現了這個錯誤。問題在於析構函數。我覺得我好笨 :( – funkadelic