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

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

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

    posts - 134,comments - 22,trackbacks - 0

    平臺 i386 win32 msvc 2003

    代碼簡單介紹:

    調度算法:輪轉法。。,可修改

    內存模型:每個線程擁有各自獨立的堆棧。啟動線程的時候,切換到對應的堆棧再啟動,使得線程之間的堆棧互不干擾

    調度方式:線程調用 schedule 函數, schedule setjmp 保存當前堆棧,選擇一個新的線程之后用 longjmp 跳轉過去。

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

    堆棧釋放:由于線程退出的時候堆棧還在使用,因此無法釋放堆棧,所以采用延后一個調度周期的辦法,等線程完全結束之后,下一次調用 schedule 的時候釋放。

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

    代碼:

      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 // 測試代碼
    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 2010-05-30 14:49 何克勤 閱讀(1084) 評論(1)  編輯  收藏 所屬分類: Linux 多線程

    FeedBack:
    # re: 用戶態非搶占式線程庫實現 (轉)
    2011-10-31 10:29 | GG大嬸
    那POXIS的用戶態多線程也是這么實現的嗎?  回復  更多評論
      
    主站蜘蛛池模板: 久9这里精品免费视频| 亚洲国产综合无码一区二区二三区| 久久亚洲国产成人影院| 国产精品免费小视频| 一级有奶水毛片免费看| 亚洲欧洲日韩在线电影| 国产精品色午夜免费视频| 中国人免费观看高清在线观看二区| 亚洲欧洲日产国码在线观看| 国产一区二区三区免费视频| 国产午夜精品免费一区二区三区| 中中文字幕亚洲无线码| 亚洲中文无韩国r级电影| 在线观看免费人成视频色9| 国产精品视频全国免费观看| 亚洲伊人精品综合在合线| 亚洲人成人网站在线观看| av免费不卡国产观看| www在线观看播放免费视频日本| 亚洲人成在线中文字幕| 久久精品夜色噜噜亚洲A∨| 国内精品乱码卡1卡2卡3免费 | 黄色网址免费在线| 2022年亚洲午夜一区二区福利| 男人的天堂亚洲一区二区三区 | 卡一卡二卡三在线入口免费| 两个人的视频www免费| 亚洲熟女综合色一区二区三区| 久久亚洲综合色一区二区三区| 台湾一级毛片永久免费| 人妻仑刮八A级毛片免费看| 亚洲欧洲国产综合| 亚洲春色在线视频| 亚洲电影日韩精品 | 日本免费一区二区在线观看| 亚州**色毛片免费观看| 亚洲 日韩 色 图网站| 亚洲午夜精品一区二区| 国产亚洲AV无码AV男人的天堂| 免费在线精品视频| 日韩激情无码免费毛片|