2015-10-08 102 views
0

最近我碰到了,其中有一個需要多線程應用程序,其主題以不同的速率運行的要求。 的問題則成了,因爲我仍然在學習多線程: 情景是考慮到把東西放到透視:多速率線程

說第一個線程在100赫茲的「實時」 第二個運行運行在10赫茲

和說第1個線程向第2個線程提供數據「myData」。

  • 如何將myData提供給第二個線程,這是通常的做法,只是讀取第一個線程中可用的任何內容,或者需要進行某種抽取以降低速率。
  • myData是否需要某種帶鎖定機制的Singleton。儘管myData不是共享的,而是由第一個線程更新並在第二個線程中使用。
  • 相反的情況如何,當一個線程中使用的數據需要以更高的速率在不同的線程中使用時。
+0

是每次使用'myData'的同一個實例還是你正在創建它的新實例?是由任何這些線程修改的'myData'。如果'myData'不是共享的,你將如何在兩個階段使用它? –

+0

只是一個簡短的說明,當你聲明你正在學習多線程時,除非它是實時操作系統,否則不能保證一個線程能夠或可以以100Hz運行,每10ms ... – ipavlu

+0

你寫了「say 1st thread runs在100赫茲「實時」第二次運行在10赫茲「我真的甚至不明白這應該是什麼意思。是的,我可以猜到,但這對解決問題來說是不好的方法。你能解釋一下嗎? –

回答

1

如何myData的將被提供給第二線程

一種常見的方法是提供一個FIFO隊列 - 這可能是一個std ::出列或鏈接列表,或無論如何 - 並且讓生產者線程將數據項推送到隊列的一端,而消費者線程將數據項從隊列的另一端彈出。確保序列化對FIFO隊列的所有訪問(使用互斥鎖或類似的鎖定機制),以避免競爭條件。

或者,而不是一個隊列,你可以有一個單一的共享數據對象(本質上是一個長的隊列),讓你的生產者線程寫入對象每次生成新的數據的時間。這可以在消費者線程看到所生成的每一條數據並不重要的情況下完成,但是它只能看到最近的數據。不過,您仍然需要進行鎖定,以避免生產者線程正在寫入數據對象的同時消費者線程從數據對象讀取的風險。

或是否需要進行某種抽取以降低速率。

不需要進行任何抽取 - 第二個線程只要讀取數據就可以讀取儘可能多的數據,無論何時喚醒。

myData是否需要某種Singleton,並鎖定 機制。

單身並不是必需的(儘管可以這樣做)。鎖定機制是必要的,除非你有某種無鎖同步機制(如果你問這個級別的問題,你沒有一個,你也不想嘗試獲得一個 - 保持簡單的事情現在!)

如何相反的情況下,當一個線程需要使用 數據在更高的速率在不同的線程中使用。

這是相同的 - 如果您使用的是正確的線程間通信機制,利率線程醒來處了也沒有關係,因爲通信機制將做正確的事情,無論何時或線程多久才醒來。

+0

很好的答案,實際上看起來替代選項更可能適用於上述情況。但是,通常如何處理同步處理...線程之間需要同步時 –

+0

找出兩個線程都訪問哪些數據項,並確保每個線程在訪問該數據項之前鎖定相同的互斥鎖,並在解鎖互斥鎖之後解鎖互斥鎖它完成對數據項的訪問,以便在線程A正在寫入數據項時(或反之亦然),線程B不會讀取(或寫入)數據項。 (例外:如果數據項不會被任何線程修改,那麼對於該數據項不需要鎖定) –

0

任何多線程程序必須應對這樣的可能性,即其中一個線程的運行速度會比另一個更快 - 即使它們在相同的CPU上以相同的時鐘頻率執行。

您的選擇包括:

  • 生產者 - 消費者容器不是讓第一個線程入隊的數據,並進行處理的第二個線程「彈出」它關閉:你可以讓隊列成長爲大內存允許,或把一些限制上之後,無論是數據會丟失或一號線將被迫放慢腳步,等待排隊進一步值

    大小
    • 有可用(例如升壓)庫,或者如果你想自己實施谷歌一些教程/文檔個互斥條件變量
  • 做概念上類似於上述哪來的大小限制爲1所以只是單myData變量,而不是一個「容器」的東西 - 但所有的同步和延遲的選擇保持不變

的Singleton模式是正交在這裏您需要:兩個線程都需要知道的數據,但通常會使用如完成函數的指針參數在線程中運行。辛格爾頓的容易過度使用和最好的避免,除非原因堆積高......