1. 程式人生 > >多執行緒還是多程序的選擇及區別

多執行緒還是多程序的選擇及區別

魚還是熊掌:淺談多程序多執行緒的選擇

關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這麼簡單了,選的不好,會讓你深受其害。

經常在網路上看到有的XDJM問“多程序好還是多執行緒好?”、“Linux下用多程序還是多執行緒?”等等期望一勞永逸的問題,我只能說:沒有最好,只有更好。根據實際情況來判斷,哪個更加合適就是哪個好。

我們按照多個不同的維度,來看看多執行緒和多程序的對比(注:因為是感性的比較,因此都是相對的,不是說一個好得不得了,另外一個差的無法忍受)。

對比維度

多程序

多執行緒

總結

資料共享、同步

資料共享複雜,需要用IPC;資料是分開的,同步簡單

因為共享程序資料,資料共享簡單,但也是因為這個原因導致同步複雜

各有優勢

記憶體、CPU

佔用記憶體多,切換複雜,CPU利用率低

佔用記憶體少,切換簡單,CPU利用率高

執行緒佔優

建立銷燬、切換

建立銷燬、切換複雜,速度慢

建立銷燬、切換簡單,速度很快

執行緒佔優

程式設計、除錯

程式設計簡單,除錯簡單

程式設計複雜,除錯複雜

程序佔優

可靠性

程序間不會互相影響

一個執行緒掛掉將導致整個程序掛掉

程序佔優

分散式

適應於多核、多機分散式;如果一臺機器不夠,擴充套件到多臺機器比較簡單

適應於多核分散式

程序佔優

1)需要頻繁建立銷燬的優先用執行緒

原因請看上面的對比。

這種原則最常見的應用就是Web伺服器了,來一個連線建立一個執行緒,斷了就銷燬執行緒,要是用程序,建立和銷燬的代價是很難承受的

2)需要進行大量計算的優先使用執行緒

所謂大量計算,當然就是要耗費很多CPU,切換頻繁了,這種情況下執行緒是最合適的。

這種原則最常見的是影象處理、演算法處理。

3)強相關的處理用執行緒,弱相關的處理用程序

什麼叫強相關、弱相關?理論上很難定義,給個簡單的例子就明白了。

一般的Server需要完成如下任務:訊息收發、訊息處理。“訊息收發”和“訊息處理”就是弱相關的任務,而“訊息處理”裡面可能又分為“訊息解碼”、“業務處理”,這兩個任務相對來說相關性就要強多了。因此“訊息收發”和“訊息處理”可以分程序設計,“訊息解碼”、“業務處理”可以分執行緒設計。

當然這種劃分方式不是一成不變的,也可以根據實際情況進行調整。

4)可能要擴充套件到多機分佈的用程序,多核分佈的用執行緒

原因請看上面對比。

5)都滿足需求的情況下,用你最熟悉、最拿手的方式

至於“資料共享、同步”、“程式設計、除錯”、“可靠性”這幾個維度的所謂的“複雜、簡單”應該怎麼取捨,我只能說:沒有明確的選擇方法。但我可以告訴你一個選擇原則:如果多程序和多執行緒都能夠滿足要求,那麼選擇你最熟悉、最拿手的那個。 

需要提醒的是:雖然我給了這麼多的選擇原則,但實際應用中基本上都是“程序+執行緒”的結合方式,千萬不要真的陷入一種非此即彼的誤區。

消耗資源:

從核心的觀點看,程序的目的就是擔當分配系統資源(CPU時間、記憶體等)的基本單位。執行緒是程序的一個執行流,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位。

執行緒,它們彼此之間使用相同的地址空間,共享大部分資料,啟動一個執行緒所花費的空間遠遠小於啟動一個程序所花費的空間,而且,執行緒間彼此切換所需的時間也遠遠小於程序間切換所需要的時間。據統計,總的說來,一個程序的開銷大約是一個執行緒開銷的30倍左右,當然,在具體的系統上,這個資料可能會有較大的區別。

通訊方式:

程序之間傳遞資料只能是通過通訊的方式,即費時又不方便。執行緒時間資料大部分共享(執行緒函式內部不共享),快捷方便。但是資料同步需要鎖對於static變數尤其注意

執行緒自身優勢:

提高應用程式響應;使多CPU系統更加有效。作業系統會保證當執行緒數不大於CPU數目時,不同的執行緒運行於不同的CPU上;

改善程式結構。一個既長又複雜的程序可以考慮分為多個執行緒,成為幾個獨立或半獨立的執行部分,這樣的程式會利於理解和修改。


實驗資料:

程序實驗程式碼(fork.c):

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <signal.h>
  4. #define P_NUMBER 255 //併發程序數量
  5. #define COUNT 5 //每次程序列印字串數
  6. #define TEST_LOGFILE "logFile.log"
  7. FILE *logFile=NULL;
  8. char *s="hello linux\0";
  9. int main()
  10. {
  11.     int i=0,j=0;
  12.     logFile=fopen(TEST_LOGFILE,"a+");//開啟日誌檔案
  13.     for(i=0;i<P_NUMBER;i++)
  14.     {
  15.         if(fork()==0)//建立子程序,if(fork()==0){}這段程式碼是子程序執行區間
  16.         {
  17.             for(j=0;j<COUNT;j++)
  18.             {
  19.                 printf("[%d]%s\n",j,s);//向控制檯輸出
  20.                 /*當你頻繁讀寫檔案的時候,Linux核心為了提高讀寫效能與速度,會將檔案在記憶體中進行快取,這部分記憶體就是Cache Memory(快取記憶體)。可能導致測試結果不準,所以在此註釋*/
  21.                 //fprintf(logFile,"[%d]%s\n",j,s);//向日志文件輸出,
  22.             }
  23.             exit(0);//子程序結束
  24.         }
  25.     }
  26.     for(i=0;i<P_NUMBER;i++)//回收子程序
  27.     {
  28.         wait(0);
  29.     }
  30.     printf("Okay\n");
  31.     return 0;
  32. }

程序實驗程式碼(thread.c):

  1. #include <pthread.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #define P_NUMBER 255//併發執行緒數量
  6. #define COUNT 5 //每執行緒列印字串數
  7. #define TEST_LOG "logFile.log"
  8. FILE *logFile=NULL;
  9. char *s="hello linux\0";
  10. print_hello_linux()//執行緒執行的函式
  11. {
  12.     int i=0;
  13.     for(i=0;i<COUNT;i++)
  14.     {
  15.         printf("[%d]%s\n",i,s);//想控制檯輸出
  16.         /*當你頻繁讀寫檔案的時候,Linux核心為了提高讀寫效能與速度,會將檔案在記憶體中進行快取,這部分記憶體就是Cache Memory(快取記憶體)。可能導致測試結果不準,所以在此註釋*/
  17.         //fprintf(logFile,"[%d]%s\n",i,s);//向日志文件輸出
  18.     }
  19.     pthread_exit(0);//執行緒結束
  20. }
  21. int main()
  22. {
  23.     int i=0;
  24.     pthread_t pid[P_NUMBER];//執行緒陣列
  25.     logFile=fopen(TEST_LOG,"a+");//開啟日誌檔案
  26.     for(i=0;i<P_NUMBER;i++)
  27.         pthread_create(&pid[i],NULL,(void *)print_hello_linux,NULL);//建立執行緒
  28.     for(i=0;i<P_NUMBER;i++)
  29.         pthread_join(pid[i],NULL);//回收執行緒
  30.     printf("Okay\n");
  31.     return 0;
  32. }

兩段程式做的事情是一樣的,都是建立“若干”個程序/執行緒,每個創建出的程序/執行緒列印“若干”條“hello linux”字串到控制檯和日誌檔案,兩個“若干”由兩個巨集 P_NUMBER和COUNT分別定義,程式編譯指令如下:
gcc -o fork fork.c
gcc -lpthread -o thread thread.c

實驗通過time指令執行兩個程式,抄錄time輸出的掛鐘時間(real時間):

time ./fork
time ./thread

每批次的實驗通過改動巨集 P_NUMBER和COUNT來調整程序/執行緒數量和列印次數,每批次測試五輪,得到的結果如下:

一、重複周麗論文實驗步驟

(注:本文平均值演算法採用的是去掉一個最大值去掉一個最小值,然後平均)

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數5

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m0.070s

 0m0.071s

0m0.071s 

0m0.070s 

0m0.070s 

0m0.070s 

多執行緒

 0m0.049s

0m0.049s 

0m0.049s 

0m0.049s 

0m0.049s 

0m0.049s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數10

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m0.112s

0m0.101s 

0m0.100s 

0m0.085s 

0m0.121s 

0m0.104s 

多執行緒

 0m0.097s

0m0.089s 

0m0.090s 

0m0.104s 

0m0.080s 

0m0.092s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數50

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m0.459s

0m0.531s 

0m0.499s 

0m0.499s 

0m0.524s 

0m0.507s 

多執行緒

 0m0.387s

0m0.456s 

0m0.435s 

0m0.423s 

0m0.408s 

0m0.422s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數100

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m1.141s

0m0.992s 

0m1.134s 

0m1.027s 

0m0.965s 

0m1.051s 

多執行緒

 0m0.925s

0m0.899s 

0m0.961s 

0m0.934s 

0m0.853s 

0m0.919s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數500

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m5.221s

0m5.258s 

0m5.706s 

0m5.288s 

0m5.455s 

0m5.334s

多執行緒

 0m4.689s

0m4.578s 

0m4.670s 

0m4.566s 

0m4.722s 

0m4.646s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數1000

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m12.680s

0m16.555s 

0m11.158s 

0m10.922s 

0m11.206s 

0m11.681s 

多執行緒

 0m12.993s

0m13.087s 

0m13.082s 

0m13.485s 

0m13.053s 

0m13.074s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數5000

第1次

第2次

第3次

第4次

第5次

平均

多程序

 1m27.348s

1m5.569s 

0m57.275s 

1m5.029s 

1m15.174s 

1m8.591s 

多執行緒

 1m25.813s

1m29.299s

1m23.842s 

1m18.914s 

1m34.872s 

1m26.318s 

單核(雙核機器禁掉一核),程序/執行緒數:255,列印次數10000

第1次

第2次

第3次

第4次

第5次

平均

多程序

 2m8.336s

2m22.999s 

2m11.046s 

2m30.040s 

2m5.752s 

2m14.137s 

多執行緒

 2m46.666s

2m44.757s 

2m34.528s 

2m15.018s 

2m41.436s 

2m40.240s 


出的結果是:任務量較大時,多程序比多執行緒效率高;而完成的任務量較小時,多執行緒比多程序要快,重複列印 600 次時,多程序與多執行緒所耗費的時間相同。

、增加每程序/執行緒的工作強度的實驗

這次將程式列印資料增大,原來列印字串為:

  1. char *s = "hello linux\0";

現在修改為每次列印256個位元組資料:

  1. char *s = "1234567890abcdef\
  2.     1234567890abcdef\
  3.     1234567890abcdef\
  4.     1234567890abcdef\
  5.     1234567890abcdef\
  6.     1234567890abcdef\
  7.     1234567890abcdef\
  8.     1234567890abcdef\
  9.     1234567890abcdef\
  10.     1234567890abcdef\
  11.     1234567890abcdef\
  12.     1234567890abcdef\
  13.     1234567890abcdef\
  14.     1234567890abcdef\
  15.     1234567890abcdef\
  16.     1234567890abcdef\0";

單核(雙核機器禁掉一核),程序/執行緒數:255  ,列印次數100

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m6.977s

 0m7.358s

 0m7.520s

 0m7.282s

 0m7.218s

 0m7.286

多執行緒

 0m7.035s

 0m7.552s

 0m7.087s

 0m7.427s

 0m7.257s

 0m7.257


單核(雙核機器禁掉一核),程序/執行緒數:  255,列印次數500

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m35.666s

 0m36.009s

 0m36.532s

 0m35.578s

 0m41.537s

 0m36.069

多執行緒

 0m37.290s

 0m35.688s

 0m36.377s

 0m36.693s

 0m36.784s

 0m36.618


單核(雙核機器禁掉一核),程序/執行緒數: 255,列印次數1000

第1次

第2次

第3次

第4次

第5次

平均

多程序

 1m8.864s

 1m11.056s

 1m10.273s

 1m12.317s

 1m20.193s

 1m11.215

多執行緒

 1m11.949s

 1m13.088s

 1m12.291s

 1m9.677s

 1m12.210s

 1m12.150



【實驗結論】

從上面的實驗比對結果看,即使Linux2.6使用了新的NPTL執行緒庫(據說比原執行緒庫效能提高了很多,唉,又是據說!),多執行緒比較多程序在效率上沒有任何的優勢,線上程數增大時多執行緒程式還出現了執行錯誤,實驗可以得出下面的結論:

在Linux2.6上,多執行緒並不比多程序速度快,考慮到執行緒棧的問題,多程序在併發上有優勢。

四、多程序和多執行緒在建立和銷燬上的效率比較

預先建立程序或執行緒可以節省程序或執行緒的建立、銷燬時間,在實際的應用中很多程式使用了這樣的策略,比如Apapche預先建立程序、Tomcat 預先建立執行緒,通常叫做程序池或執行緒池。在大部分人的概念中,程序或執行緒的建立、銷燬是比較耗時的,在stevesn的著作《Unix網路程式設計》中有這樣 的對比圖(第一卷 第三版 30章 客戶/伺服器程式設計正規化):

行號 伺服器描述 程序控制CPU時間(秒,與基準之差)
Solaris2.5.1 Digital Unix4.0b BSD/OS3.0
0 迭代伺服器(基準測試,無程序控制) 0.0 0.0 0.0
1 簡單併發服務,為每個客戶請求fork一個程序 504.2 168.9 29.6
2 預先派生子程序,每個子程序呼叫accept 6.2 1.8
3 預先派生子程序,用檔案鎖保護accept 25.2 10.0 2.7
4 預先派生子程序,用執行緒互斥鎖保護accept 21.5
5 預先派生子程序,由父程序向子程序傳遞套接字 36.7 10.9 6.1
6 併發服務,為每個客戶請求建立一個執行緒 18.7 4.7
7 預先建立執行緒,用互斥鎖保護accept 8.6 3.5
8 預先建立執行緒,由主執行緒呼叫accept 14.5 5.0

stevens已駕鶴西去多年,但《Unix網路程式設計》一書仍具有巨大的影響力,上表中stevens比較了三種伺服器上多程序和多執行緒的執行效 率,因為三種伺服器所用計算機不同,表中資料只能縱向比較,而橫向無可比性,stevens在書中提供了這些測試程式的原始碼(也可以在網上下載)。書中介 紹了測試環境,兩臺與伺服器處於同一子網的客戶機,每個客戶併發5個程序(伺服器同一時間最多10個連線),每個客戶請求從伺服器獲取4000位元組資料, 預先派生子程序或執行緒的數量是15個。

第0行是迭代模式的基準測試程式,伺服器程式只有一個程序在執行(同一時間只能處理一個客戶請求),因為沒有程序或執行緒的排程切換,因此它的速度是 最快的,表中其他服務模式的執行數值是比迭代模式多出的差值。迭代模式很少用到,在現有的網際網路服務中,DNS、NTP服務有它的影子。第1~5行是多進 程服務模式,期中第1行使用現場fork子程序,2~5行都是預先建立15個子程序模式,在多程序程式中套接字傳遞不太容易(相對於多線 程),stevens在這裡提供了4個不同的處理accept的方法。6~8行是多執行緒服務模式,第6行是現場為客戶請求建立子執行緒,7~8行是預先建立 15個執行緒。表中有的格子是空白的,是因為這個系統不支援此種模式,比如當年的BSD不支援執行緒,因此BSD上多執行緒的資料都是空白的。

從資料的比對看,現場為每客戶fork一個程序的方式是最慢的,差不多有20倍的速度差異,Solaris上的現場fork和預先建立子程序的最大差別是504.2 :21.5,但我們不能理解為預先建立模式比現場fork快20倍,原因有兩個:

1. stevens的測試已是十幾年前的了,現在的OS和CPU已起了翻天覆地的變化,表中的數值需要重新測試。

2. stevens沒有提供伺服器程式整體的執行計時,我們無法理解504.2 :21.5的實際執行效率,有可能是1504.2 : 1021.5,也可能是100503.2 : 100021.5,20倍的差異可能很大,也可能可以忽略。

因此我寫了下面的實驗程式,來計算在Linux2.6上建立、銷燬10萬個程序/執行緒的絕對用時。

建立10萬個程序(forkcreat.c):

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <sys/types.h>
  8. #include <sys/wait.h>
  9. int count;//子程序建立成功數量 
  10. int fcount;//子程序建立失敗數量 
  11. int scount;//子程序回收數量 
  12. /*訊號處理函式–子程序關閉收集*/
  13. void sig_chld(int signo)
  14. {
  15.     pid_t chldpid;//子程序id
  16.     int stat;//子程序的終止狀態
  17.     //子程序回收,避免出現殭屍程序
  18.     while((chldpid=wait(&stat)>0))
  19.     {
  20.         scount++;
  21.     }
  22. }
  23. int main()
  24. {
  25.     //註冊子程序回收訊號處理函式
  26.     signal(SIGCHLD,sig_chld);
  27.     int i;
  28.     for(i=0;i<100000;i++)//fork()10萬個子程序
  29.     {
  30.         pid_t pid=fork();
  31.         if(pid==-1)//子程序建立失敗
  32.         {
  33.             fcount++;
  34.         }
  35.         else if(pid>0)//子程序建立成功
  36.         {
  37.             count++;
  38.         }
  39.         else if(pid==0)//子程序執行過程
  40.         {
  41.             exit(0);
  42.         }
  43.     }
  44.     printf("count:%d fount:%d scount:%d\n",count,fcount,scount);
  45. }

建立10萬個執行緒(pthreadcreat.c):

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. int count=0;//成功建立執行緒數量
  4. void thread(void)
  5. {
  6.     //啥也不做
  7. }
  8. int main(void)
  9. {
  10.     pthread_t id;//執行緒id
  11.     int i,ret;
  12.     for(i=0;i<100000;i++)//建立10萬個執行緒
  13.     {
  14.         ret=pthread_create(&id,NULL,(void *)thread,NULL);
  15.         if(ret!=0)
  16.         {
  17.             printf("Create pthread error!\n");
  18.             return(1);
  19.         }
  20.         count++;
  21.         pthread_join(id,NULL);
  22.     }
  23.     printf("count:%d\n",count);
  24. }

建立10萬個執行緒的Java程式:

  1. public class ThreadTest
  2.     {
  3.         public static void main(String[] ags) throws InterruptedException
  4.         {
  5.             System.out.println("開始執行");
  6.             long start = System.currentTimeMillis();
  7.             for(int i = 0; i < 100000; i++) //建立10萬個執行緒
  8.             {
  9.                 Thread athread = new Thread(); //建立執行緒物件
  10.                 athread.start(); //啟動執行緒
  11.                 athread.join(); //等待該執行緒停止
  12.             }
  13.             System.out.println("用時:" + (System.currentTimeMillis() – start) + " 毫秒");
  14.         }
  15.     }

單核(雙核機器禁掉一核),建立銷燬10萬個程序/執行緒

第1次

第2次

第3次

第4次

第5次

平均

多程序

 0m8.774s

 0m8.780s

 0m8.475s

 0m8.592s

 0m8.687s

 0m8.684

多執行緒

 0m0.663s

 0m0.660s

 0m0.662s

 0m0.660s

 0m0.661s

 0m0.661

建立銷燬10萬個執行緒(Java)
12286毫秒

從資料可以看出,多執行緒比多程序在效率上有10多倍的優勢,但不能讓我們在使用哪種併發模式上定性,這讓我想起多年前政治課上的一個場景:在講到優越性時,面對著幾個對此發表質疑評論的調皮男生,我們的政治老師發表了高見,“不能只橫向地和當今的發達國家比,你應該縱向地和過去中國幾十年的發展歷史 比”。政治老師的話套用在當前簡直就是真理,我們看看,即使是在賽揚CPU上,建立、銷燬程序/執行緒的速度都是空前的,可以說是有質的飛躍的,平均建立銷燬一個程序的速度是0.18毫秒,對於當前伺服器幾百、幾千的併發量,還有預先派生子程序/執行緒的必要嗎?

預先派生子程序/執行緒比現場建立子程序/執行緒要複雜很多,不僅要對池中程序/執行緒數量進行動態管理,還要解決多程序/多執行緒對accept的“搶” 問題,在stevens的測試程式中,使用了“驚群”和“鎖”技術。即使stevens的資料表格中,預先派生執行緒也不見得比現場建立執行緒快,在 《Unix網路程式設計》第三版中,新作者參照stevens的測試也提供了一組資料,在這組資料中,現場建立執行緒模式比預先派生執行緒模式已有了效率上的優勢。因此我對這一節實驗下的結論是:

預先派生程序/執行緒的模式(程序池、執行緒池)技術,不僅複雜,在效率上也無優勢,在新的應用中可以放心大膽地為客戶連線請求去現場建立程序和執行緒。

我想,這是fork迷們最願意看到的結論了。

五、雙核系統重複周麗論文實驗步驟

雙核,程序/執行緒數:255 ,列印次數10

第1次

第2次

第3次

第4次

第5次

平均(單核倍數)

多程序

0m0.061s

0m0.053s

0m0.068s

0m0.061s

0m0.059s

 0m0.060(1.73)

多執行緒

0m0.054s

0m0.040s

0m0.053s

0m0.056s

0m0.042s

 0m0.050(1.84)

雙核,程序/執行緒數: 255,列印次數100

第1次

第2次

第3次

第4次

第5次

平均(單核倍數)

多程序

0m0.918s

0m1.198s

0m1.241s

0m1.017s

 0m1.172s

 0m1.129(0.93)

多執行緒

0m0.897s

0m1.166s

0m1.091s 

0m1.360s

 0m0.997s

 0m1.085(0.85)

雙核,程序/執行緒數: 255,列印次數1000

第1次

第2次

第3次

第4次

第5次

平均(單核倍數)

多程序

相關推薦

執行還是程序選擇區別

魚還是熊掌:淺談多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這麼簡單了,選的不好,會讓你深受其害。 經常在網路上看到有的XDJM問“多程序好還是多執

linux伺服器執行還是程序選擇區別

轉自http://blog.csdn.net/lishenglong666/article/details/8557215 魚還是熊掌:淺談多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這

python中執行程序選擇問題

多執行緒與多程序的選擇問題 既然python中多執行緒和多程序都能夠進行非同步操作,那麼到底應該如何選擇 首先我們必須知道GIL全域性解釋鎖對執行緒的影響,其同一時間只能夠允許一個執行緒進入cpu進行執行,因此對於cpu密集型的程式並不適用於多執行緒操作 cpu密集型的功能對cp

執行程序Python實現【理論部分】

計算機的核心是CPU,它承擔了所有的計算任務。它就像一座工廠,時刻在執行。 假定工廠的電力有限,一次只能供給一個車間使用。也就是說,一個車間開工的時候,其他車間都必須停工。背後的含義就是,單個CPU一次只能執行一個任務。 程序就好比工廠的車間,它代表CPU所能處理的單個任務。任一時刻,CPU總是執行一個程序

執行程序Python實現【Python實現程序

上一篇部落格介紹了多執行緒與多程序的理論部分,這篇部落格將參考部落格以及各種教程完成Python多程序實現部分。 multiprocessing模組 Process 類 multiprocessing.Process(group=None, target=N

python中執行程序協程概念程式設計上的應用

1, 多執行緒    執行緒是程序的一個實體,是CPU進行排程的最小單位,他是比程序更小能獨立執行的基本單位。  執行緒基本不擁有系統資源,只佔用一點執行中的資源(如程式計數器,一組暫存器和棧),但是它可以與同屬於一個程序的其他執行緒共享全部的資源。  提高程式的執行速率

程序執行之間的通訊方式通訊實現步驟小結

程序間通訊方式 # 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。 # 有名管道 (namedpipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。 #

python中執行程序協程概念程式設計上的應用!

1, 多執行緒 執行緒是程序的一個實體,是 CPU進行排程的最小單位,他是比程序更小能獨立執行的基本單位。 執行緒基本不擁有系統資源,只佔用一點執行中的資源(如程式計數器,一組暫存器和棧),但是它可以與同屬於一個程序的其他執行緒共享全部的資源。 提高程式的執行速率,上下文切換快

執行程序區別選擇

魚還是熊掌:淺談多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這麼簡單了,選的不好,會讓你深受其害。 經常在網路上看到有的XDJM問“多程序好

python執行程序選擇,以及優劣勢

多執行緒用於IO密集型,如socket,爬蟲,web 多程序用於計算密集型,如金融分析 如果四個任務是計算密集型,多核意味著平行計算,在python中一個程序中同一時刻只有一個執行緒執行用不上多核,方案一勝 如果四個任務是I/O

執行以及執行程序選擇

開發十年,就只剩下這套架構體系了! >>>   

Python執行程序和協程的例項講解

執行緒、程序和協程是什麼 執行緒、程序和協程的詳細概念解釋和原理剖析不是本文的重點,本文重點講述在Python中怎樣實際使用這三種東西 參考: 程序、執行緒、協程之概念理解 程序(Process)是計算機中的程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統結構的基礎。執

Python爬蟲之執行程序

前言 我們之前寫的爬蟲都是單個執行緒的?這怎麼夠?一旦一個地方卡到不動了,那不就永遠等待下去了?為此我們可以使用多執行緒或者多程序來處理。 首先宣告一點! 多執行緒和多程序是不一樣的!一個是 thread 庫,一個是 multiprocessing 庫。而多執行緒 thread 在 Pytho

python執行程序、協程的使用

本文主要介紹多執行緒、多程序、協程的最常見使用,每個的詳細說明與介紹有時間會在以後的隨筆中體現。 一、多執行緒 1.python通過兩個標準庫thread和threading提供對執行緒的支援。thread提供了低級別的、原始的執行緒以及一個簡單的鎖。threading通過對thread模組

執行 vs 程序

- 程式:一堆程式碼以文字形式存入一個文件 - 程序:程式執行的一個狀態(鄰居對門的關係)        - 包含地址,空間,記憶體,資料棧等         - 每個程序有

[進階]-執行程序、非同步IO實用例子

在編寫爬蟲時,效能的消耗主要在IO請求中,當單程序單執行緒模式下請求URL時必然會引起等待,從而使得請求整體變慢。以下程式碼預設執行環境為python3。 目錄 一、多執行緒、多程序 1.同步執行 2.多執行緒執行 3.多執行緒+回撥函式執行 4.多程序執行 5.多程

java執行、FutureTask的用法兩種常用的使用場景

Java多執行緒實現的方式有四種 1.繼承Thread類,重寫run方法 2.實現Runnable介面,重寫run方法,實現Runnable介面的實現類的例項物件作為Thread建構函式的target 3.通過Callable和FutureTask建立執行緒 4.通過執行緒池

python 執行程序, 協程

1. 介紹: threading用於提供執行緒相關的操作,執行緒是應用程式中工作的最小單元。python當前版本的多執行緒庫沒有實現優先順序、執行緒組,執行緒也不能被停止、暫停、恢復、中斷。 2. 1  執行緒執行函式 #!/bin/python #coding:utf8 import

python執行————8、執行程序對比

#多程序程式設計 #耗cpu的操作,用多程序程式設計,對於io操作來說,使用多執行緒程式設計,程序切換代價要高於執行緒 import time from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor,as_compl

執行程序之比較,以及三種執行模型。

工作幾年找工作幾乎總會被問,從最開始的從網上看答案,到現在憑自己的經驗去說,這個問題似乎也是經驗積累的一個驗證,最近沒事就總結一下吧: 程序和執行緒的定義、比較等: 程序:處於活動狀態的計算機程式。程序就是在作業系統中       執行特定的任務,程序針對