我對多執行緒與程式設計效率的認知

2021-05-11 09:32:46 字數 1597 閱讀 1458

因為專案裡多執行緒用的很多,所以也小小深入的研究了下多執行緒與程式設計效率問題。一直想寫這篇文章,但是沒時間寫。現在我來談談我的認知。

引用網上乙個淺顯的例子來解釋多執行緒:

cpu是乙個挖隧道的工人。有兩種開挖隧道的方法:

1.只在山的一頭挖,直到挖到山的另一頭,從而打通隧道,完成任務。這是單執行緒。

2.在山的兩頭向中間挖,同時開工,最後在山的中間接通,從而打通隧道,這感覺肯定比第一種方法快多了,這就是多執行緒。

但是,是這樣簡單的嗎?當然不是。如果我們只有

1個人,也就是只有1個

cpu,如果只跑這

2個任務,那麼,這個工人只有山的兩頭跑,這頭挖一會,再去挖那一頭,以實現上面第二種多執行緒方案。但是,這樣的效率遠不如單執行緒高,因為來回跑是要花費額外時間的。這就好比執行緒的排程和上下文切換。

那麼,我們是不是可以說,在單

cpu的機器中,多執行緒反而降低了效率呢?

答案很明顯,當然不是。以上的假設只是在單

cpu單核、純計算、沒

io的理想

cpu狀態,單個執行緒肯定比多個執行緒快,因為省去了執行緒切換的開銷。但真實的環境基本都有

io操作,所以執行緒會有阻塞的存在(比如為了等待硬碟操作,某一線程被掛起),因此,當某個任務被阻塞了,如果程式是單執行緒的,那麼,整個程式就停下了。如果是多執行緒,那麼其他沒有阻塞的執行緒還可以繼續執行,所以就快了。可以說,從效能上,如果沒有執行緒阻塞,那麼單

cpu上的多執行緒就沒有任何意義了。

我們在加上現實的環境。現代作業系統都是多使用者多工的系統。因此,

cpu時間是由作業系統進行分配。因為除了你的程式外,系統上海由其他若干任務(包括作業系統本身)在跑,所以你的程式不會連續時間在跑。因此,多執行緒是相當有必要的。是提高程式效率的最好途徑之一。但是不是任何情況下都要多執行緒呢?當然也不是。這也需要根據情況來看。

再舉個程式設計上的例子。假設有乙個資料庫。在同一時間內,有很多使用者需要訪問這個資料庫。那麼,我們怎麼設計這個資料庫連線呢?這就需要分情況:

如果這麼多使用者都訪問資料庫中的同乙個表(或者僅

2~3個表),由於資料庫鎖的設計成同一時間只允許乙個連線訪問某乙個表。因此,在這種狀態下,設計成單執行緒是最好的。因為很多使用者的訪問會在單執行緒內形成乙個佇列,輪流去查詢這個表。如果設計成多執行緒連線資料庫,那麼,這麼多執行緒還是會等待,輪流去查詢這個表。但是由於有執行緒的上下文切換時間以及排程時間存在,所以,多執行緒效率毫無疑問遠不如單執行緒高。

但是如果如此多的使用者去訪問很多不同的表,那麼,根據上面的原理,效率無疑比單執行緒高多了。

回到一開頭

cpu挖山的例子。我們套上正確的多執行緒的思想,那麼,此例應該如下:

如果乙個機械人代表

cpu,那麼這個機械人一天所做的事情,並不都是只挖山。它還有許多事情要做,比如砍柴,燒水,釣魚,挖山等等。

如果按以上劃分是

4條執行緒,每乙個執行緒大概占用

1/4 cpu

時間。如果你把挖山這一任務多設幾次,比如設定成挖山共有

3條執行緒。那麼挖山的

cpu佔用率將達到

1/2,這就是所謂的提高了效率。

現實中的

cpu

在大部分時候的閒置狀態的。因此開多條執行緒能提高效率,倒不如說成是充分利用了

cpu執行時間。

我對C 的認知。

關於開發者的技術水平到底該如何定義,到底乙個人的技術水平應該定位在高 中 低的標準是什麼呢?很多人覺得這是乙個仁者見仁的問題,有人覺得根據公司的那個員工等級判斷。答案是肯定不是,從純開發技術的角度來分析。很多人覺得自己一門語言精通了就去學其他語言了,美其名曰集大成者,這樣的工作十幾年卻是初級水平的技...

我對DDD的認知(一)

ddd,全名 domain driven design,中文名 領域驅動設計。分層的架構方式是我們常用的,這裡的分層是說n layer,指的是邏輯的分層,目的是分離職責。常用的是三層 表現層,業務邏輯層,資料訪問層。ddd把原來經典三層 表現層,業務邏輯層,資料訪問層 中的業務邏輯層又細分為兩層 應...

我對DDD的認知(一)

ddd,全名 domain driven design,中文名 領域驅動設計。分層的架構方式是我們常用的,這裡的分層是說n layer,指的是邏輯的分層,目的是分離職責。常用的是三層 表現層,業務邏輯層,資料訪問層。ddd把原來經典三層 表現層,業務邏輯層,資料訪問層 中的業務邏輯層又細分為兩層 應...