2012-05-21 79 views
0

我有兩個線程(我在GNU/Linux上使用pthreads)。現在他們使用全局變量共享信息(我知道,這不是很好)。在每個循環結束時,他們必須將5個變量(doubles)的值發送到另一個線程。 我想在其通信信道引入一個固定的時間延遲,延遲兩個線程之間的通信

線程1(1kHz時)< ---> 10ms的< --->線程2(1kHz時)

我在想,在每個週期中,我都可以創建一個讀取值的線程,睡眠10ms,然後將其轉發到另一個線程,然後死亡。 這將使系統在每個週期創建2個線程,每個通信通道的每個方向一個線程(每毫秒2個線程)。

是否有任何其他智能方式來模擬通信延遲?

更新:我不想同步線程的通信,但它們之間添加一個延遲。 如果thread1在1s時間寫入內容,另一個線程只能在1s + 10ms時間內讀取它。

+0

爲什麼你需要創建新線程每一次? – HonkyTonk

+1

您是否想將此延遲作爲同步的手段?如果是的話,這是一個可怕的想法。如果沒有,那麼爲什麼延遲? –

+0

@DavidHeffernan:我**需要**添加一個延遲才能重現網絡中的通信延遲。 – Claudio

回答

1

這聽起來不像性能問題,所以簡單一點。無需複雜的數據結構,額外的線程等。

爲您的數據創建一個結構,爲其添加一個時間戳字段。

製作一個數組來保存至少10個結構。去100爲安全。這裏不會用很多記憶,所以誰在乎。只要需要增長,你就可以把它變成malloc。

每個線程都有一個這樣的數組,以及數組中的項數。

當一個線程準備發送數據時,做兩件事情:

  1. 檢查第一項的時間戳在它的陣列,如果老 足夠的數據發送給其他線程。在發送之後,遞減 計數,並將數組中的其餘項減少一個 缺口。
  2. 電流/新數據添加到與 當前時間戳陣列的端和遞增計數。

重複其他線程。

+0

這似乎是一個很好的方法,謝謝! – Claudio

+1

你仍然需要某種形式的線程同步機制,爲數據發送部分 – Attila

+0

我同意,我希望這個問題是更多的辦法有消息採取10ms的去其他線程。本地FIFO解決了這個問題。他仍然需要使用原子操作或互斥來同步數據。 – johnnycrash

0

爲什麼不使用互斥鎖來同步兩個線程之間的通信呢?

當第一個線程需要寫入數據時,它獲取互斥鎖(因此其他線程在第一次更新數據時無法讀取數據),更新數據,然後釋放互斥鎖。另一個線程在讀取數據時會執行類似的獲取/釋放方法。

+0

好像OP希望全局變量像FIFO一樣行事,並且這種方法不能保證行爲(例如,在讀者線程之前,寫入程序線程無法獲取互斥鎖,寫入數據,釋放互斥鎖,然後再次獲取互斥鎖知道了嗎?) – gcbenison

+0

是的,@ gcbenison是對的。不管怎麼說,還是要謝謝你! – Claudio

0

從作者和讀者線程之間的通信是否需要可靠的問題我不能完全說明(例如:寫者線程發送的所有消息都保證被讀者線程看到,按照正確的順序) 。如果是這樣,並且如果您使用單個全局結構作爲共享數據,則您基本上實現了緩衝區大小爲1的FIFO。線程間通信錯誤很容易,因此我建議您查看一些內容像glib的asynchronous queues。如果您需要從頭開始實施自己的項目,那麼查看該代碼可能是一個很好的開始。

+0

溝通需要可靠,我會看看鏈接!謝謝! – Claudio

0

爲什麼不能在這裏使用一個信號?您可以讓一個線程等待信號量,並讓其他線程在完成關鍵部分時發出信號。

+0

我不想讓線程等待,只有從一個線程到另一個線程的信息。不管怎麼說,還是要謝謝你! – Claudio

+0

@claudio如果你想在線程之間進行可靠的通信,那麼必須有一個線程等待另一個線程的機制。它可能不會最終在實踐中等待,取決於時間,但機制需要在那裏以確保正確的行爲。否則,在編寫器線程只寫完一半的情況下,如何防止讀者線程讀取? – gcbenison

+0

@nighthawk你不需要兩個信號燈嗎?這是一個經典的[生產者 - 消費者問題](http://en.wikipedia.org/wiki/Producer-consumer_problem),其緩衝區大小爲1,傳統上使用兩個二進制信號量來實現(一個計算滿槽,一個這可能是空插槽) – gcbenison