我目前有一些多線程難題。我有兩個線程,一個讀取串行數據,另一個嘗試從數據中提取數據包。這兩個線程共享一個隊列。試圖創建包線程有一個名爲解析與以下聲明功能:指向STL容器線程安全的指針(隊列/ Deque)
Parse(std::queue<uint8_t>* data, pthread_mutex_t* lock);
本質上講,它需要一個指向STL隊列,並使用pop()方法,因爲它經過隊列找包。由於任何pop()被鎖定,並且在Parse函數和將數據推送到隊列中的線程之間共享此鎖,所以使用該鎖。這樣,可以在數據被主動添加到隊列時解析隊列。
代碼似乎工作的大部分,但我看到無效數據包在一個比我想象的更高的速度。我的主要問題是,我想知道指針是否正在改變,而我正在讀取隊列中的數據。例如,如果第一個線程推送了一堆數據,那麼在內存中發現隊列的位置是否有可能改變?或者我保證即使添加數據,指向隊列的指針也會保持不變?我擔心隊列的內存可以在我的Parse()函數中重新分配,因此在我的函數中間,指針會失效。
例如,我知道某些STL迭代器對某些操作是無效的。但是,我傳遞一個指向容器本身的指針。就是這樣的:
// somewhere in my code I create a queue
std::queue<uint8_t> queue;
// elsewhere...
Parse(&queue, &lock_shared_between_the_two_threads);
指向容器本身的指針是否會失效?它指向什麼?第一個元素,或...?
請注意,我不是指向任何給定的元素,而是指向容器本身。另外,我從來沒有指定應該使用哪個底層容器來實現隊列,所以在它下面,它只是一個雙端隊列。
任何幫助將不勝感激。
編輯8/1:
我能夠在我的代碼上運行一些測試。幾點:
容器本身的指針不改變我的程序的生命週期。這是有道理的,因爲隊列本身是一個類的成員變量。也就是說,儘管隊列的元素是動態分配的,但隊列本身並不是這種情況。
我遇到的壞包似乎是我收到的串行數據的函數。我將所有數據都轉儲到了一個十六進制文件,並能夠找到無效的數據包,並且我的算法正確地將它們標記爲這樣。
其結果是,我在想傳遞一個引用或指針到一個STL容器放入一個函數是線程安全的,但我想聽到更多的評論確保這種情況下,或如果這是特定於實現的(因爲很多STL是...)。
也許我錯過了它,但是你在* push()'和'pop()'操作中是否使用'lock'?如果不是,你應該是。 –
對不起,是的,鎖用於所有推送和彈出操作。據我所知,這些操作應該沒有併發問題。 –
您可以設計一個解析算法的單線程測試,以消除潛在的線程安全問題作爲潛在的原因嗎?基本上,捕獲大量的原始數據,構建一個隊列,然後讓解析器在它上面鬆動,並查看是否有同樣的問題。 –