• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 31  文章 - 128  trackbacks - 0
            <2007年3月>
            25262728123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(5)

            隨筆分類(lèi)(38)

            隨筆檔案(31)

            收藏夾(4)

            College

            High School

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 55926
            • 排名 - 407

            最新評(píng)論

            • 1.?re: [yc]詳解link
            • 面試的時(shí)候面試官就問(wèn)過(guò)我什么是編譯和鏈接,我說(shuō)編譯就是把代碼文件生成目標(biāo)文件,鏈接就是把目標(biāo)文件生成可執(zhí)行文件,他說(shuō)不對(duì),又問(wèn)我什么是動(dòng)態(tài)鏈接,還問(wèn)我預(yù)編譯都做什么處理。。。都在這里找到了答案!!!!
            • --王至乾
            • 2.?re: [yc]詳解link
            • @劉偉
              我是說(shuō)博主,不是叫你啊
            • --溪流
            • 3.?re: [yc]詳解link
            • 誰(shuí)是石老師,我不是哈@溪流
            • --劉偉
            • 4.?re: [yc]詳解link
            • 石老師?我是溪流~
            • --溪流
            • 5.?re: [yc]詳解link
            • 期待樓主下文啊,多謝樓主了
            • --劉偉

            閱讀排行榜

            評(píng)論排行榜

            平臺(tái) i386 win32 msvc 2003

             

            代碼簡(jiǎn)單介紹:

             

            調(diào)度算法:輪轉(zhuǎn)法。。,可修改

             

            內(nèi)存模型:每個(gè)線(xiàn)程擁有各自獨(dú)立的堆棧。啟動(dòng)線(xiàn)程的時(shí)候,切換到對(duì)應(yīng)的堆棧再啟動(dòng),使得線(xiàn)程之間的堆棧互不干擾

             

            調(diào)度方式:線(xiàn)程調(diào)用 schedule 函數(shù), schedule setjmp 保存當(dāng)前堆棧,選擇一個(gè)新的線(xiàn)程之后用 longjmp 跳轉(zhuǎn)過(guò)去。

             

            線(xiàn)程退出:線(xiàn)程函數(shù)的返回即意味著線(xiàn)程的退出,可以在線(xiàn)程函數(shù)的任何位置上退出。退出后返回到 start_thread 函數(shù)里,此后該函數(shù)將退出線(xiàn)程的 slot 從鏈表里刪除,如果還有別的線(xiàn)程那么再繼續(xù)調(diào)度,否則跳轉(zhuǎn)出最外層。

             

            堆棧釋放:由于線(xiàn)程退出的時(shí)候堆棧還在使用,因此無(wú)法釋放堆棧,所以采用延后一個(gè)調(diào)度周期的辦法,等線(xiàn)程完全結(jié)束之后,下一次調(diào)用 schedule 的時(shí)候釋放。

             

            問(wèn)題:切換線(xiàn)程的時(shí)候, longjmp 不會(huì)恢復(fù)通用寄存器的值,因此要么函數(shù)內(nèi)的局部變量都加上 volatile ,要么在 setjmp 之前手動(dòng)保存, longjmp 之后手動(dòng)恢復(fù)(可以在庫(kù)的實(shí)現(xiàn)方完成,但是會(huì)增大不可移植的面積,現(xiàn)在暫不考慮加入)。

             

            代碼:

              1 // Cothread.h
              2 #include  < setjmp.h >
              3
              4 typedef void ( * thread_func_t)(void * );
              5
              6 typedef struct sched_slot
              7 {
              8     jmp_buf buf;
              9      int  has_set;
             10     thread_func_t thread;
             11     void *  arg;
             12     char *  stack;
             13 } sched_slot;
             14
             15
             16 typedef struct slot_list
             17 {
             18     sched_slot slot;
             19     struct slot_list *   next ;
             20 } slot_list;
             21
             22 typedef struct sched_system
             23 {
             24     slot_list *  threads;
             25     slot_list *  current;
             26      int  main_esp, main_ebp;
             27     char  * unfreed_stack;
             28      int  retaddr;
             29 } sched_system;
             30
             31
             32 extern sched_system sys;
             33
             34 void reg_thread(thread_func_t f, void *  arg);
             35
             36 void free_unfree_stack();
             37     
             38 void schedule();
             39
             40 void start_first_thread();
             41
             42
             43
             44
             45
             46
             47 // cothread.c
             48 #include  < assert.h >
             49 #include  < stdlib.h >
             50 #include  < setjmp.h >
             51 #include  " cothread.h "
             52 #define CHANGE_STACK(newaddr) _asm mov esp, newaddr
             53 #define STACK_SIZE  65536
             54 #define RESERVED_STACK  4
             55
             56
             57
             58
             59
             60
             61 sched_system sys;
             62
             63
             64 void reg_thread(thread_func_t f, void *  arg)
             65 {
             66     slot_list *  new_thread  =  (slot_list * )malloc(sizeof(slot_list));
             67     new_thread -> next   =  sys.threads;
             68     sys.threads  =  new_thread;
             69     new_thread -> slot.arg  =  arg;
             70     new_thread -> slot.has_set  =   0 ;
             71     new_thread -> slot.stack  =   0 ;
             72     new_thread -> slot.thread  =  f;
             73 }
             74
             75
             76 void free_unfree_stack()
             77 {
             78      if  (sys.unfreed_stack)
             79     {
             80         free(sys.unfreed_stack);
             81         sys.unfreed_stack  =   0 ;
             82     }
             83 }
             84 void start_thread(slot_list *  iter);
             85
             86
             87 void schedule()
             88 {
             89     slot_list *  old;
             90     free_unfree_stack();
             91     old  =  sys.current;
             92     sys.current  =  sys.current -> next ;
             93      if  (!sys.current)
             94     {
             95         sys.current  =  sys.threads;
             96     }
             97     
             98      if  (!setjmp(old -> slot.buf))
             99     {
            100         old -> slot.has_set  =   1 ;
            101
            102          if  (sys.current -> slot.has_set)
            103             longjmp(sys.current -> slot.buf,  1 );
            104          else
            105             start_thread(sys.current);
            106         
            107     }
            108 }
            109
            110
            111 static void exit_thread()
            112 {
            113     slot_list *  iter;
            114     free_unfree_stack();
            115      if  (sys.current  ==  sys.threads)
            116     {
            117         sys.threads  =  sys.threads -> next ;
            118         sys.unfreed_stack  =  sys.current -> slot.stack;
            119         free(sys.current);
            120         sys.current  =  sys.threads;
            121     }
            122      else
            123     {
            124     
            125          for  (iter  =  sys.threads; iter  &&  iter -> next  ! =  sys.current  &&  iter -> next  ! =   0 ; iter  =  iter -> next )
            126             ;
            127         assert (iter  &&  iter -> next   ==  sys.current);
            128         iter -> next   =  sys.current -> next ;
            129         sys.unfreed_stack  =  sys.current -> slot.stack;
            130         free(sys.current);
            131         sys.current  =  iter -> next ;
            132     }
            133
            134      if  (sys.current  ==   0 )
            135     {
            136         sys.current  =  sys.threads;
            137     }
            138
            139      if  (sys.current)
            140     {
            141
            142          if  (sys.current -> slot.has_set)
            143             longjmp(sys.current -> slot.buf,  1 );
            144          else
            145             start_thread(sys.current);
            146     }
            147 }
            148
            149 static jmp_buf buf;
            150
            151 static void start_thread(slot_list *  iter)
            152 {
            153     char *  stack_btm;
            154     static thread_func_t thread;
            155     static void *  arg;
            156
            157     iter -> slot.stack  =  (char * )malloc(STACK_SIZE  +  RESERVED_STACK);
            158     stack_btm  =  iter -> slot.stack  +  STACK_SIZE;
            159     thread  =  iter -> slot.thread;
            160     arg  =  iter -> slot.arg;
            161     CHANGE_STACK(stack_btm);
            162     thread(arg);
            163      if  (sys.threads -> next )
            164         exit_thread();
            165      else
            166     {
            167         sys.unfreed_stack  =  sys.threads -> slot.stack;
            168         free(sys.threads);
            169         longjmp(buf,  1 );
            170     }
            171 }
            172
            173 void start_first_thread()
            174 {
            175      if  (!setjmp(buf))
            176     {
            177         sys.current  =  sys.threads;
            178         start_thread(sys.current);
            179     }
            180     free_unfree_stack();
            181 }
            182
            183
            184
            185
            186
            187 // 測(cè)試代碼
            188 // test.c
            189
            190
            191 #include  < stdio.h >
            192 #include  < Windows.h >
            193 #include  " cothread.h "
            194 void f0(void *  p)
            195 {
            196     register  int  i;
            197      for  (i  =   0  ; i  <   3 ++ i)
            198     {
            199         printf( " %d, %d\n " 0 , i); 
            200         Sleep( 200 );
            201         schedule();
            202     }
            203      // exit_thread();
            204 }
            205
            206 void f1(void *  p)
            207 {
            208     register  int  i;
            209      for  (i  =   0  ; ;  ++ i)
            210     {
            211          if  (i  ==   6 )
            212             return;
            213         printf( " %d, %d\n " 1 , i); 
            214         Sleep( 200 );
            215         schedule();
            216     }
            217 }
            218
            219 void f3(void *  p)
            220 {
            221     register  int  i;
            222      for  (i  =   0  ; i <   6 ++ i)
            223     {
            224         printf( " %d, %d\n " 3 , i); 
            225         Sleep( 200 );
            226         schedule();
            227     }
            228 }
            229
            230
            231 void f2(void *  p)
            232 {
            233     register  int  i;
            234      for  (i  =   0  ;i  <   12  ;  ++ i)
            235     {
            236         printf( " %d, %d\n " 2 , i); 
            237         Sleep( 200 );
            238         schedule();
            239          if  (i  ==   8 )
            240         {
            241             reg_thread(f3,  0 );
            242         }
            243     }
            244 }
            245
            246
            247
            248
            249
            250 int  main()
            251 {
            252
            253
            254     reg_thread(f0,  0 );
            255     reg_thread(f1,  0 );
            256     reg_thread(f2,  0 );
            257
            258     start_first_thread();
            259     printf( " finished\n " );
            260     getchar();
            261     
            262 }
            263
            264
            posted on 2007-03-16 16:33 shifan3 閱讀(3314) 評(píng)論(4)  編輯 收藏 引用 所屬分類(lèi): C++

            FeedBack:
            # re: 用戶(hù)態(tài)非搶占式線(xiàn)程庫(kù)實(shí)現(xiàn) 2007-03-16 23:44 pluskid
            哦?是在每個(gè)線(xiàn)程里面都要收工調(diào)用 schedule() 函數(shù)來(lái)切換線(xiàn)程的嗎?  回復(fù)  更多評(píng)論
              
            # re: 用戶(hù)態(tài)非搶占式線(xiàn)程庫(kù)實(shí)現(xiàn) 2007-03-17 02:52 Francis Arcanum
            @pluskid
            是的  回復(fù)  更多評(píng)論
              
            # re: [yc]用戶(hù)態(tài)非搶占式線(xiàn)程庫(kù)實(shí)現(xiàn) 2007-05-08 11:25 Rhythm
            我想不通……一個(gè)用來(lái)貼代碼的blog系統(tǒng),代碼本身為啥不是等寬字體?  回復(fù)  更多評(píng)論
              
            # re: [yc]用戶(hù)態(tài)非搶占式線(xiàn)程庫(kù)實(shí)現(xiàn) 2007-05-08 14:12 Francis Arcanum
            @Rhythm
            我錯(cuò)了,貌似是我沒(méi)選擇字體。。。  回復(fù)  更多評(píng)論
              
            国产日韩久久久精品影院首页| 亚洲国产欧美国产综合久久 | 精品久久久久久无码专区| 性做久久久久久久| 高清免费久久午夜精品| 99久久国产综合精品成人影院| 久久亚洲中文字幕精品一区| 久久只有这里有精品4| 久久精品国产网红主播| 热久久国产精品| 久久福利资源国产精品999| 久久综合给久久狠狠97色| 国产高清美女一级a毛片久久w| 久久精品国产亚洲7777| 久久亚洲日韩精品一区二区三区| 久久久久四虎国产精品| 久久五月精品中文字幕| 久久久久亚洲AV无码网站| 久久久99精品成人片中文字幕| 亚洲综合伊人久久大杳蕉| 99久久国产主播综合精品| 亚洲精品无码久久久久sm| 国产激情久久久久影院老熟女| 亚洲色大成网站www久久九| 热久久国产精品| 久久久久人妻一区精品性色av| 国産精品久久久久久久| 久久精品亚洲日本波多野结衣| 久久综合视频网站| 久久国产精品成人免费| 99精品久久久久久久婷婷| 国产香蕉97碰碰久久人人| 精品乱码久久久久久久| 一极黄色视频久久网站| 99久久伊人精品综合观看| 久久精品国产亚洲AV嫖农村妇女| 久久一区二区三区免费| 国产精品免费看久久久香蕉| 久久99久久99小草精品免视看 | 欧美精品一区二区精品久久| 亚洲AV无码久久|