簡體   English   中英

我應該了解多線程以及何時使用它,主要是在c ++中

[英]What should I know about multithreading and when to use it, mainly in c++

我從未遇到多線程,但我到處都聽說過它。 我應該知道什么以及何時使用它? 我的代碼主要是用c ++編寫的。

大多數情況下,您需要了解應用程序需要運行的操作系統上的MT庫。 除非C ++ 0x成為現實(現在看起來很長),否則不支持正確的語言或線程的標准庫。 我建議你看看用於* nix和Windows線程的POSIX標准pthreads庫來開始。

這是我的觀點,但多線程的最大問題是難度很大。 我並不是說從經驗豐富的程序員的角度來看,我的意思是它在概念上。 一旦你深入並行編程,就會出現很多困難的並發問題。 這是眾所周知的,並且有許多方法可以使應用程序開發人員更容易實現並發。 功能語言因其缺乏副作用和冪等性而變得更受歡迎。 一些供應商選擇隱藏API背后的並發性(如Apple的Core Animation)。

多頭程序可以看到性能上的巨大收益(用戶感知和完成的實際工作量),但您必須花時間來理解代碼和數據結構的交互。

MSDN Multithreading for Rookies文章可能值得一讀。 來自Microsoft,它是根據Microsoft OS支持的內容(1993年編輯)編寫的,但大多數基本思想同樣適用於其他系統,具有適當的功能重命名等。

這是一個很大的主題。

幾點......

  • 對於多核,多線程的重要性現在是巨大的。 如果您不是多線程,則無法獲得該機器的全部性能。
  • 多線程很難 正確的線程之間的通信和同步是棘手的​​。 問題通常是間歇性的,難以診斷,如果設計不適合多線程,很難修復。
  • 多線程目前大多是非便攜式和平台特定的。

有一些可移植的庫,包含有線程API的包裝器。 提升是一個。 wxWidgets(主要是GUI庫)是另一個。 可以合理地移植,但您不會擁有從特定於平台的API獲得的所有選項。

這是一個關於POSIX線程編程 (帶圖表)的優秀教程的鏈接,可以幫助您入門。 雖然本教程是特定於pthread的,但許多概念都轉移到其他系統。

要了解有關何時使用線程的更多信息,有助於對並行編程有基本的了解。 這是一個關於並行計算基礎知識的教程的鏈接,旨在幫助那些剛剛熟悉該主題的人。

我已經介紹了你可能會覺得有用的多線程

在本文中,沒有一行代碼,它的目的不是教授任何給定編程語言中多線程編程的復雜性,而是簡要介紹,主要關注如何以及特別是多線程編程為何以及何時有用。

對方回復涵蓋了如何組成部分,我將簡要提及何時使用多線程。

多線程的主要替代方案是使用計時器。 例如,考慮您需要在存在文件的情況下更新表單上的小標簽。 如果文件存在,則需要繪制特殊圖標或其他內容。 現在,如果您使用具有低超時的計時器,您可以實現基本相同的功能,該功能可以輪詢文件是否存在非常頻繁並更新您的ui。 沒有額外的麻煩。

但是你的功能正在做很多不必要的工作,不是嗎。 操作系統提供了“嘿此文件已創建”原語,使您的線程處於休眠狀態,直到文件准備就緒。 顯然你不能在ui線程中使用它,否則整個應用程序會凍結,所以你生成一個新線程並將其設置為等待文件創建事件。

現在你的應用程序正在使用盡可能少的cpu,因為線程可以等待事件(無論是使用互斥鎖還是事件)。 但是說你的文件准備好了。 你不能從不同的線程更新你的ui,因為如果2個線程試圖同時改變相同的內存位,那么所有的地獄都會破裂。 事實上,這是非常糟糕的,以至於windows flat out拒絕你完成它的嘗試。

所以現在你需要一種同步機制來與ui一個接一個地連接(串行),所以你不要踩到彼此的腳趾,但是你不能編寫主線程部分,因為ui循環隱藏在內部視窗。

另一種方法是使用另一種方式在線程之間進行通信。 在這種情況下,您可以使用PostMessage將消息發布到已找到文件的主ui循環並執行其工作。

現在,如果你的工作無法等待,並且不能很好地分成小部分(用於短暫超時計時器),你剩下的就是另一個線程以及由此產生的所有同步問題。

這可能是值得的。 或者在調試你錯過的奇怪競爭條件的幾天和幾天之后,它可能會讓你陷入困境。 首先花費很長時間嘗試將其分成小塊用於計時器可能會有所回報。 即使你做不到,在少數情況下你可以超過時間成本。

你應該知道這很難。 有些人認為這是不可能的,沒有實際的方法來驗證程序是否是線程安全的。 sqlite的作者Hipp博士表示, 線程是邪惡的。 本文詳細介紹了線程問題

Chrome瀏覽器使用進程而不是線程,像Stackless Python這樣的工具避免了硬件支持的線程,而支持解釋器支持的“微線程”。 甚至像Web服務器這樣的東西,你認為線程將是一個完美的契合,並轉向事件驅動的架構。

我自己也不會說這是不可能的:很多人都嘗試過並且成功了。 但毫無疑問,編寫生產質量的多線程代碼真的很難。 成功的多線程應用程序傾向於僅使用幾個預定的線程,只需經過一些仔細分析的通信點。 例如,只有兩個線程的游戲,物理和渲染,或者具有UI線程和后台線程的GUI應用程序,沒有別的。 在整個代碼庫中產生和加入線程的程序肯定會有許多不可能發現的間歇性錯誤。

它在C ++中特別難,原​​因有兩個:

  1. 標准的當前版本根本沒有提到線程 所有線程庫以及特定於平台和實現。
  2. 與Java這樣的語言相比,被認為是原子操作的范圍相當狹窄。

boost Threads這樣的跨平台庫可以緩解這種局面。 未來的C ++ 0x將引入一些線程支持。 但是,boost還具有良好的進程間通信支持,您可以使用它來完全避免線程。

如果你對線程沒有任何其他知識,那么它很難並且應該得到尊重,而不是你認識99%以上的程序員。

畢竟,如果你能夠編寫一個不會隨機發生段錯誤的多線程C ++程序,那么你仍然有興趣開始漫長的艱難道路,那么我建議從Boost線程開始。 他們有良好的文檔記錄,高水平,跨平台工作。 概念(互斥鎖,鎖,期貨)與所有線程庫中存在的幾個關鍵概念相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM