<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    多線程的那點兒事(基礎篇)

    多線程編程是現代軟件技術中很重要的一個環節。要弄懂多線程,這就要牽涉到多進程?當然,要了解到多進程,就要涉及到操作系統。不過大家也不要緊張,聽我慢慢道來。這其中的環節其實并不復雜。

      (1)單CPU下的多線程

      在沒有出現多核CPU之前,我們的計算資源是唯一的。如果系統中有多個任務要處理的話,那么就需要按照某種規則依次調度這些任務進行處理。什么規則呢?可以是一些簡單的調度方法,比如說

      1)按照優先級調度

      2)按照FIFO調度

      3)按照時間片調度等等

      當然,除了CPU資源之外,系統中還有一些其他的資源需要共享,比如說內存、文件、端口、socket等。既然前面說到系統中的資源是有限的,那么獲取這些資源的最小單元體是什么呢,其實就是進程。

      舉個例子來說,在linux上面每一個享有資源的個體稱為task_struct,實際上和我們說的進程是一樣的。我們可以看看task_struct(linux 0.11代碼)都包括哪些內容

  • struct task_struct {  
  • /* these are hardcoded - don't touch */  
  •     long state; /* -1 unrunnable, 0 runnable, >0 stopped */  
  •     long counter;  
  •     long priority;  
  •     long signal;  
  •     struct sigaction sigaction[32];  
  •     long blocked;   /* bitmap of masked signals */  
  • /* various fields */  
  •     int exit_code;  
  •     unsigned long start_code,end_code,end_data,brk,start_stack;  
  •     long pid,father,pgrp,session,leader;  
  •     unsigned short uid,euid,suid;  
  •     unsigned short gid,egid,sgid;  
  •     long alarm;  
  •     long utime,stime,cutime,cstime,start_time;  
  •     unsigned short used_math;  
  • /* file system info */  
  •     int tty;        /* -1 if no tty, so it must be signed */  
  •     unsigned short umask;  
  •     struct m_inode * pwd;  
  •     struct m_inode * root;  
  •     struct m_inode * executable;  
  •     unsigned long close_on_exec;  
  •     struct file * filp[NR_OPEN];  
  • /* ldt for this task 0 - zero 1 - cs 2 - ds&ss */  
  •     struct desc_struct ldt[3];  
  • /* tss for this task */  
  •     struct tss_struct tss;  
  • };
  •   每一個task都有自己的pid,在系統中資源的分配都是按照pid進行處理的。這也就說明,進程確實是資源分配的主體。

      這時候,可能有朋友會問了,既然task_struct是資源分配的主體,那為什么又出來thread?為什么系統調度的時候是按照thread調度,而不是按照進程調度呢?原因其實很簡單,進程之間的數據溝通非常麻煩,因為我們之所以把這些進程分開,不正是希望它們之間不要相互影響嘛。

      假設是兩個進程之間數據傳輸,那么需要如果需要對共享數據進行訪問需要哪些步驟呢

      1)創建共享內存

      2)訪問共享內存->系統調用->讀取數據

      3)寫入共享內存->系統調用->寫入數據

     要是寫個代碼,大家可能就更明白了

  • #include <unistd.h>   
  • #include <stdio.h>   
  •   
  • int value = 10;  
  •   
  • int main(int argc, char* argv[])  
  • {  
  •     int pid = fork();  
  •     if(!pid){  
  •         Value = 12;  
  •         return 0;  
  •     }  
  •     printf("value = %d\n", value);  
  •     return 1;  
  • }
  •   上面的代碼是一個創建子進程的代碼,我們發現打印的value數值還是10。盡管中間創建了子進程,修改了value的數值,但是我們發現打印下來的數值并沒有發生改變,這就說明了不同的進程之間內存上是不共享的。

      那么,如果修改成thread有什么好處呢?其實最大的好處就是每個thread除了享受單獨cpu調度的機會,還能共享每個進程下的所有資源。要是調度的單位是進程,那么每個進程只能干一件事情,但是進程之間是需要相互交互數據的,而進程之間的數據都需要系統調用才能應用,這在無形之中就降低了數據的處理效率。

      (2)多核CPU下的多線程

      沒有出現多核之前,我們的CPU實際上是按照某種規則對線程依次進行調度的。在某一個特定的時刻,CPU執行的還是某一個特定的線程。然而,現在有了多核CPU,一切變得不一樣了,因為在某一時刻很有可能確實是n個任務在n個核上運行。我們可以編寫一個簡單的open mp測試一下,如果還是一個核,運行的時間就應該是一樣的。

  • #include <omp.h>   
  • #define MAX_VALUE 10000000   
  •   
  • double _test(int value)  
  • {  
  •     int index;  
  •     double result;  
  •   
  •     result = 0.0;  
  •     for(index = value + 1; index < MAX_VALUE; index +=2 )  
  •         result += 1.0 / index;  
  •   
  •     return result;  
  • }  
  •   
  • void test()  
  • {  
  •     int index;  
  •     int time1;  
  •     int time2;  
  •     double value1,value2;  
  •     double result[2];  
  •   
  •     time1 = 0;  
  •     time2 = 0;  
  •   
  •     value1 = 0.0;  
  •     time1 = GetTickCount();  
  •     for(index = 1; index < MAX_VALUE; index ++)  
  •         value1 += 1.0 / index;  
  •   
  •     time1 = GetTickCount() - time1;  
  •   
  •     value2 = 0.0;  
  •     memset(result , 0, sizeof(double) * 2);  
  •     time2 = GetTickCount();  
  •   
  • #pragma omp parallel for   
  •     for(index = 0; index < 2; index++)  
  •         result[index] = _test(index);  
  •   
  •     value2 = result[0] + result[1];  
  •     time2 = GetTickCount() - time2;  
  •   
  •     printf("time1 = %d,time2 = %d\n",time1,time2);  
  •     return;  
  • }
  •   (3)多線程編程

      為什么要多線程編程呢?這其中的原因很多,我們可以舉例解決

      1)有的是為了提高運行的速度,比如多核cpu下的多線程

      2)有的是為了提高資源的利用率,比如在網絡環境下下載資源時,時延常常很高,我們可以通過不同的thread從不同的地方獲取資源,這樣可以提高效率

      3)有的為了提供更好的服務,比如說是服務器

      4)其他需要多線程編程的地方等等

    posted on 2011-12-08 14:28 順其自然EVO 閱讀(173) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    <2011年12月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 91网站免费观看| 亚洲国产高清美女在线观看| 日韩一区二区a片免费观看 | 国产在线国偷精品免费看| 亚洲av无码不卡久久| 久久精品国产99精品国产亚洲性色| 国产大片线上免费看| 中文字幕无码不卡免费视频| 国产精品白浆在线观看免费| 黄页网址在线免费观看| 亚洲国产成人综合精品| 亚洲国产情侣一区二区三区| 久久91亚洲精品中文字幕| 最新国产AV无码专区亚洲| 免费一级一片一毛片| 免费无码又爽又刺激高潮| 成人免费毛片内射美女-百度| 老汉精品免费AV在线播放| 久久免费动漫品精老司机| 香蕉视频在线免费看| 有色视频在线观看免费高清在线直播| 亚洲精品久久无码| 中国亚洲呦女专区| 自拍偷区亚洲国内自拍| 中文字幕无码亚洲欧洲日韩| 亚洲 欧洲 自拍 另类 校园| 亚洲人成黄网在线观看| 亚洲欧洲日韩综合| 亚洲人成影院77777| 亚洲中文久久精品无码1 | av大片在线无码免费| 在线成人爽a毛片免费软件| 亚洲免费在线视频| 91成人在线免费视频| 最近中文字幕大全中文字幕免费| 99精品视频免费在线观看| 最近2019年免费中文字幕高清| 久久免费的精品国产V∧| 四虎免费影院ww4164h| 美女网站免费福利视频| 毛片a级毛片免费观看免下载 |