多線程編程是現代軟件技術中很重要的一個環節。要弄懂多線程,這就要牽涉到多進程?當然,要了解到多進程,就要涉及到操作系統。不過大家也不要緊張,聽我慢慢道來。這其中的環節其實并不復雜。
(1)單CPU下的多線程
在沒有出現多核CPU之前,我們的計算資源是唯一的。如果系統中有多個任務要處理的話,那么就需要按照某種規則依次調度這些任務進行處理。什么規則呢?可以是一些簡單的調度方法,比如說
“
1)按照優先級調度
2)按照FIFO調度
3)按照時間片調度等等
當然,除了CPU資源之外,系統中還有一些其他的資源需要共享,比如說內存、文件、端口、socket等。既然前面說到系統中的資源是有限的,那么獲取這些資源的最小單元體是什么呢,其實就是進程。
舉個例子來說,在Linux上面每一個享有資源的個體稱為task_struct,實際上和我們說的進程是一樣的。我們可以看看task_struct(linux 0.11代碼)都包括哪些內容,
1.structtask_struct{
2./*thesearehardcoded-don'ttouch*/
3.longstate;/*-1unrunnable,0runnable,>0stopped*/
4.longcounter;
5.longpriority;
6.longsignal;
7.structsigactionsigaction[32];
8.longblocked;/*bitmapofmaskedsignals*/
9./*variousfields*/
10.intexit_code;
11.unsignedlongstart_code,end_code,end_data,brk,start_stack;
12.longpid,father,pgrp,session,leader;
13.unsignedshortuid,euid,suid;
14.unsignedshortgid,egid,sgid;
15.longalarm;
16.longutime,stime,cutime,cstime,start_time;
17.unsignedshortused_math;
18./*filesysteminfo*/
19.inttty;/*-1ifnotty,soitmustbesigned*/
20.unsignedshortumask;
21.structm_inode*pwd;
22.structm_inode*root;
23.structm_inode*executable;
24.unsignedlongclose_on_exec;
25.structfile*filp[NR_OPEN];
26./*ldtforthistask0-zero1-cs2-ds&ss*/
27.structdesc_structldt[3];
28./*tssforthistask*/
29.structtss_structtss;
30.};
每一個task都有自己的pid,在系統中資源的分配都是按照pid進行處理的。這也就說明,進程確實是資源分配的主體。
這時候,可能有朋友會問了,既然task_struct是資源分配的主體,那為什么又出來thread?為什么系統調度的時候是按照thread調度,而不是按照進程調度呢?原因其實很簡單,進程之間的數據溝通非常麻煩,因為我們之所以把這些進程分開,不正是希望它們之間不要相互影響嘛。
假設是兩個進程之間數據傳輸,那么需要如果需要對共享數據進行訪問需要哪些步驟呢
“
1)創建共享內存
2)訪問共享內存->系統調用->讀取數據
3)寫入共享內存->系統調用->寫入數據
要是寫個代碼,大家可能就更明白了,
1.#include
2.#include
3.
4.intvalue=10;
5.
6.intmain(intargc,char*argv[])
7.{
8.intpid=fork();
9.if(!pid){
10.Value=12;
11.return0;
12.}
13.printf("value=%d ",value);
14.return1;
15.}
上面的代碼是一個創建子進程的代碼,我們發現打印的value數值還是10。盡管中間創建了子進程,修改了value的數值,但是我們發現打印下來的數值并沒有發生改變,這就說明了不同的進程之間內存上是不共享的。
那么,如果修改成thread有什么好處呢?其實最大的好處就是每個thread除了享受單獨cpu調度的機會,還能共享每個進程下的所有資源。要是調度的單位是進程,那么每個進程只能干一件事情,但是進程之間是需要相互交互數據的,而進程之間的數據都需要系統調用才能應用,這在無形之中就降低了數據的處理效率。
(2)多核CPU下的多線程
沒有出現多核之前,我們的CPU實際上是按照某種規則對線程依次進行調度的。在某一個特定的時刻,CPU執行的還是某一個特定的線程。然而,現在有了多核CPU,一切變得不一樣了,因為在某一時刻很有可能確實是n個任務在n個核上運行。我們可以編寫一個簡單的open mp測試一下,如果還是一個核,運行的時間就應該是一樣的。
1.#include
2.#defineMAX_VALUE10000000
3.
4.double_test(intvalue)
5.{
6.intindex;
7.doubleresult;
8.
9.result=0.0;
10.for(index=value+1;index
11.result+=1.0/index;
12.
13.returnresult;
14.}
15.
16.voidtest()
17.{
18.intindex;
19.inttime1;
20.inttime2;
21.doublevalue1,value2;
22.doubleresult[2];
23.
24.time1=0;
25.time2=0;
26.
27.value1=0.0;
28.time1=GetTickCount();
29.for(index=1;index
30.value1+=1.0/index;
31.
32.time1=GetTickCount()-time1;
33.
34.value2=0.0;
35.memset(result,0,sizeof(double)*2);
36.time2=GetTickCount();
37.
38.#pragmaompparallelfor
39.for(index=0;index2;?index++)??
40.result[index]=_test(index);
41.
42.value2=result[0]+result[1];
43.time2=GetTickCount()-time2;
44.
45.printf("time1=%d,time2=%d ",time1,time2);
46.return;
47.}
(3)多線程編程
為什么要多線程編程呢?這其中的原因很多,我們可以舉例解決
1)有的是為了提高運行的速度,比如多核cpu下的多線程
2)有的是為了提高資源的利用率,比如在網絡環境下下載資源時,時延常常很高,我們可以通過不同的thread從不同的地方獲取資源,這樣可以提高效率
3)有的為了提供更好的服務,比如說是服務器
4)其他需要多線程編程的地方等等
-
cpu
+關注
關注
68文章
11037瀏覽量
216016 -
操作系統
+關注
關注
37文章
7091瀏覽量
124963 -
多線程編程
+關注
關注
0文章
17瀏覽量
6776
原文標題:多核CPU下的多線程編程原來是這么回事...
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
工控一體機多線程任務調度優化:聚徽分享破解工業復雜流程高效協同密碼
進程、線程、協程傻傻分不清?一文帶你徹底扒光它們的\"底褲\"!
請問如何在Python中實現多線程與多進程的協作?
請問rt-thread studio如何進行多線程編譯?
迅為3A6000開發板/龍芯3A6000與龍芯3A5000等龍架構處理器軟件兼容
迅為3A6000_7A2000開發板龍芯全國產處理器與龍芯 3A5000完全兼容
一文搞懂Linux進程的睡眠和喚醒
Python中多線程和多進程的區別

迅為3A6000_7A2000核心主板龍芯全國產處理器LoongArch架構
LWIP多線程強烈建議開啟LWIP_ASSERT_CORE_LOCKED宏,這個在RTT里面要怎么實現?
從多線程設計模式到對 CompletableFuture 的應用

評論