青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 31  文章 - 128  trackbacks - 0
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(5)

隨筆分類(38)

隨筆檔案(31)

收藏夾(4)

College

High School

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 57067
  • 排名 - 407

最新評論

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

閱讀排行榜

評論排行榜

平臺 i386 win32 msvc 2003

 

代碼簡單介紹:

 

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

 

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

 

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

 

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

 

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

 

問題:切換線程的時候, longjmp 不會恢復(fù)通用寄存器的值,因此要么函數(shù)內(nèi)的局部變量都加上 volatile ,要么在 setjmp 之前手動保存, longjmp 之后手動恢復(fù)(可以在庫的實現(xiàn)方完成,但是會增大不可移植的面積,現(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 // 測試代碼
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 閱讀(3359) 評論(4)  編輯 收藏 引用 所屬分類: C++

FeedBack:
# re: 用戶態(tài)非搶占式線程庫實現(xiàn) 2007-03-16 23:44 pluskid
哦?是在每個線程里面都要收工調(diào)用 schedule() 函數(shù)來切換線程的嗎?  回復(fù)  更多評論
  
# re: 用戶態(tài)非搶占式線程庫實現(xiàn) 2007-03-17 02:52 Francis Arcanum
@pluskid
是的  回復(fù)  更多評論
  
# re: [yc]用戶態(tài)非搶占式線程庫實現(xiàn) 2007-05-08 11:25 Rhythm
我想不通……一個用來貼代碼的blog系統(tǒng),代碼本身為啥不是等寬字體?  回復(fù)  更多評論
  
# re: [yc]用戶態(tài)非搶占式線程庫實現(xiàn) 2007-05-08 14:12 Francis Arcanum
@Rhythm
我錯了,貌似是我沒選擇字體。。。  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              亚洲欧美卡通另类91av | 99re热精品| 亚洲免费精品| 欧美日韩国产专区| 中文精品视频| 久久久精品动漫| 曰韩精品一区二区| 欧美精品一区二区三区很污很色的 | 久久亚洲电影| 亚洲高清资源综合久久精品| 欧美成人精品一区二区| 99re热这里只有精品免费视频| 亚洲欧美在线x视频| 黄色成人av在线| 欧美久久电影| 亚洲在线一区二区| 欧美成年人在线观看| aa成人免费视频| 国产亚洲精久久久久久| 老司机免费视频久久| 夜夜爽99久久国产综合精品女不卡| 午夜精品福利电影| 亚洲第一精品夜夜躁人人爽| 欧美日韩在线播放| 欧美中文字幕| 亚洲精品美女在线| 久久久精品动漫| 一区二区三区毛片| 狠狠色丁香婷婷综合影院| 欧美伦理91i| 久久国产精品久久w女人spa| 日韩亚洲在线观看| 可以看av的网站久久看| 亚洲线精品一区二区三区八戒| 激情婷婷久久| 国产精品一区一区三区| 欧美成人一区二免费视频软件| 亚洲永久免费| 最近看过的日韩成人| 久久久亚洲一区| 亚洲天堂av图片| 亚洲国产精品久久久| 国产精品自拍在线| 欧美视频免费| 女人天堂亚洲aⅴ在线观看| 午夜欧美视频| 中日韩高清电影网| 亚洲国产欧美国产综合一区| 久久综合图片| 久久不射中文字幕| 午夜精品国产精品大乳美女| 日韩一级免费观看| 亚洲欧洲日产国产网站| 海角社区69精品视频| 国产精品一区二区a| 欧美天堂亚洲电影院在线播放| 免费在线一区二区| 久久夜色精品一区| 久久精品国产亚洲5555| 欧美在线视频a| 亚洲欧美大片| 亚洲欧美精品一区| 亚洲男女毛片无遮挡| 宅男噜噜噜66一区二区| 一区二区三区回区在观看免费视频| 亚洲国产老妈| 亚洲国产一区二区三区a毛片| 农夫在线精品视频免费观看| 久久尤物视频| 美女主播视频一区| 麻豆成人在线观看| 免费在线看一区| 媚黑女一区二区| 欧美大香线蕉线伊人久久国产精品| 久久先锋影音av| 毛片基地黄久久久久久天堂| 久久网站热最新地址| 毛片一区二区三区| 欧美激情va永久在线播放| 欧美激情视频在线播放| 亚洲国产成人精品久久| 亚洲精品乱码视频| 亚洲素人在线| 久久爱www久久做| 久久综合综合久久综合| 欧美成人自拍| 欧美日韩国产综合新一区| 欧美亚州在线观看| 国产欧美精品在线| 伊人久久成人| 日韩午夜在线观看视频| 亚洲手机成人高清视频| 午夜精品久久久久久久99水蜜桃| 欧美在线视频观看免费网站| 久久久国产亚洲精品| 欧美成人性生活| 亚洲精品色婷婷福利天堂| 亚洲午夜日本在线观看| 欧美一区二区精美| 欧美成人午夜激情在线| 国产精品久久波多野结衣| 国产亚洲在线| 亚洲人成久久| 西西人体一区二区| 免费人成精品欧美精品| 亚洲国内欧美| 亚洲欧美在线网| 老司机久久99久久精品播放免费| 欧美精品在线网站| 国产一区二区欧美日韩| 日韩性生活视频| 久久动漫亚洲| 亚洲欧洲精品一区二区三区| 亚洲欧美日韩精品| 蜜臀va亚洲va欧美va天堂| 国产精品久久二区二区| 亚洲国产成人一区| 亚洲欧美综合一区| 亚洲国产精品va在线看黑人| 亚洲网站视频| 欧美大片在线看免费观看| 国产欧美日韩免费| 亚洲美女在线视频| 久久久久久夜| 一区二区三区欧美成人| 久久影视精品| 国产日韩成人精品| 一区二区三区精品国产| 免费日韩av电影| 午夜在线一区二区| 欧美日韩免费观看一区二区三区 | 一区二区三区高清在线| 看片网站欧美日韩| 国产欧美日韩视频一区二区| 亚洲免费观看高清在线观看| 久久亚洲精品一区| 亚洲在线日韩| 欧美午夜视频在线| 亚洲精品视频一区二区三区| 老巨人导航500精品| 亚洲午夜极品| 欧美视频一区在线| 99国产精品视频免费观看一公开| 久久综合综合久久综合| 亚洲欧美日韩国产中文在线| 欧美特黄一区| 一区二区三区国产在线| 亚洲电影免费观看高清完整版| 欧美在线一二三| 国产区精品在线观看| 午夜国产精品视频| 亚洲少妇诱惑| 欧美午夜不卡视频| 亚洲色图自拍| 日韩亚洲视频| 欧美日韩国产一级片| 99爱精品视频| 最新国产成人av网站网址麻豆 | 99国产成+人+综合+亚洲欧美| 欧美a级一区| 久久夜色精品国产欧美乱极品| 国产一区二区三区久久精品| 欧美在线视频一区| 午夜国产欧美理论在线播放| 国产精品香蕉在线观看| 性欧美长视频| 亚洲欧美日本国产有色| 国产精品一区视频| 欧美一区二区成人6969| 午夜精品av| 国产在线视频不卡二| 久久久精品久久久久| 久久久久久精| 亚洲激情av在线| 亚洲激情在线| 欧美视频在线观看| 午夜精品久久| 欧美一区综合| 亚洲国产欧美另类丝袜| 亚洲黄色免费电影| 欧美日韩国产综合视频在线| 亚洲伊人网站| 羞羞答答国产精品www一本| 国精产品99永久一区一区| 欧美成人在线免费观看| 欧美日本精品| 校园激情久久| 久久亚洲春色中文字幕久久久| 亚洲国产日韩欧美一区二区三区| 91久久精品美女| 国产精品免费观看视频| 久久人人精品| 欧美精品一二三| 午夜精品一区二区三区电影天堂| 欧美中文在线字幕| 亚洲美女中文字幕| 亚洲欧美日韩精品久久亚洲区| 在线不卡免费欧美| 一本一本久久a久久精品综合麻豆| 国产美女精品在线|