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

隨筆 - 31  文章 - 128  trackbacks - 0
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(5)

隨筆分類(38)

隨筆檔案(31)

收藏夾(4)

College

High School

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 56680
  • 排名 - 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 閱讀(3346) 評論(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>
              亚洲欧美日韩视频一区| 亚洲高清123| 欧美自拍丝袜亚洲| 一本色道久久综合亚洲精品按摩| 欧美淫片网站| 久久久国产精品一区| 校园激情久久| 久久久国产成人精品| 久久夜色精品一区| 亚洲人成久久| 99精品国产在热久久| 一本色道**综合亚洲精品蜜桃冫| 亚洲日本国产| 欧美在线综合视频| 欧美国产日本在线| 国产精品久久婷婷六月丁香| 国产视频亚洲精品| 欧美肥婆bbw| 欧美jizz19hd性欧美| 欧美日韩网站| 亚洲成人在线视频网站| 亚洲午夜精品国产| 美女视频黄免费的久久| 亚洲一区二区三区色| 美女黄网久久| 国产亚洲精品久久久久动| 日韩一级片网址| 久久尤物视频| 欧美亚洲三区| 国产精品一区视频网站| 亚洲一区999| 亚洲人体影院| 欧美99在线视频观看| 在线视频成人| 免费永久网站黄欧美| 香港成人在线视频| 国产热re99久久6国产精品| 亚洲视频免费在线| 99视频精品全部免费在线| 欧美日韩国产综合视频在线观看| 亚洲日本成人网| 亚洲精品久久久一区二区三区| 麻豆精品传媒视频| 日韩网站在线观看| 一区二区免费看| 国产精品最新自拍| 老司机亚洲精品| 女人香蕉久久**毛片精品| 日韩午夜精品视频| 麻豆成人91精品二区三区| 在线观看欧美日本| 在线观看国产精品淫| 欧美三区在线视频| 久久国产色av| 久久综合九九| 亚洲欧美日韩国产综合精品二区| aa级大片欧美三级| 韩日精品视频| 一本色道久久综合狠狠躁篇怎么玩 | 在线综合亚洲欧美在线视频| 欧美日本韩国| 你懂的国产精品永久在线| 欧美日韩第一页| 男人插女人欧美| 国产精品视频导航| 91久久国产综合久久91精品网站| 欧美日韩亚洲高清| 亚洲电影在线观看| 一区精品在线| 久久在线免费| 免费在线亚洲欧美| 国产日本亚洲高清| 一本久道久久综合中文字幕| 亚洲九九爱视频| 欧美精品偷拍| 亚洲欧洲日产国产综合网| 亚洲第一精品久久忘忧草社区| 欧美一级黄色网| 猫咪成人在线观看| 亚洲国产女人aaa毛片在线| 久久亚洲一区| 亚洲黄色尤物视频| 中文在线不卡| 国产综合久久久久久鬼色| 欧美一区日本一区韩国一区| 久久精品视频网| 新67194成人永久网站| 欧美日本中文| 99精品国产99久久久久久福利| 亚洲午夜免费福利视频| 国产一区二区三区久久悠悠色av | 一区二区在线视频播放| 性视频1819p久久| 久久精品国产久精国产一老狼 | 国产日产高清欧美一区二区三区| 亚洲精品永久免费| 日韩视频久久| 国产精品理论片| 午夜精品久久久久| 久久一区二区三区四区五区| 国内成人在线| 欧美激情a∨在线视频播放| 正在播放欧美一区| 亚洲国产视频一区二区| 销魂美女一区二区三区视频在线| 在线日韩视频| 开心色5月久久精品| 性久久久久久久久| 久久美女性网| 欧美精品久久99久久在免费线| 欧美性大战久久久久| 久久综合色天天久久综合图片| 亚洲精品精选| 亚洲影院免费| 欧美在线视频导航| 欧美激情导航| 狠狠色综合网站久久久久久久| 国产精品手机视频| 国产精品二区在线| 美乳少妇欧美精品| 久久综合色综合88| 在线亚洲一区二区| 亚洲欧美综合国产精品一区| 久久精品一本久久99精品| 美日韩在线观看| 男同欧美伦乱| 欧美亚一区二区| 亚洲第一在线综合网站| 亚洲欧洲精品一区二区| 久久黄色级2电影| 久久人人爽爽爽人久久久| 欧美与欧洲交xxxx免费观看| 久久精彩免费视频| 欧美jizz19hd性欧美| 中文欧美日韩| 久久久在线视频| 欧美日韩日本视频| 国产情侣一区| 日韩视频永久免费| 久久gogo国模啪啪人体图| 欧美激情女人20p| 亚洲图片在线观看| 欧美福利一区二区| 亚洲国产导航| 久久久久女教师免费一区| 一区二区三区视频在线观看| 久久久国产视频91| 国产曰批免费观看久久久| 亚洲黄网站在线观看| 久久久久青草大香线综合精品| 亚洲免费小视频| 欧美女激情福利| 亚洲国产黄色| 欧美激情一区二区三区高清视频| 亚洲免费视频一区二区| 国产精品草草| 欧美一级免费视频| 亚洲影院色无极综合| 亚洲视频精品| 亚洲人成在线影院| 亚洲欧美日韩国产| 欧美诱惑福利视频| 伊人精品久久久久7777| 亚洲无玛一区| 亚洲另类黄色| 欧美成人在线免费视频| 黄色国产精品| 久久久久国产精品一区| 久久精品动漫| 亚欧成人精品| 国产九色精品成人porny| 亚洲私人影院| 久久亚洲综合色| 噜噜噜躁狠狠躁狠狠精品视频| 国产日韩欧美一区在线| 亚洲一区在线播放| 欧美一区二区三区视频在线观看 | 欧美chengren| 免费日韩视频| 亚洲人午夜精品免费| 欧美国产一区二区在线观看| 欧美成人一二三| 亚洲尤物在线| 国产欧美一区二区三区久久| 午夜日韩福利| 欧美激情在线免费观看| 亚洲日韩视频| 国产日韩欧美精品在线| 久久综合九色综合久99| 亚洲国产精选| 久久爱www| 一本大道久久精品懂色aⅴ| 国产精品免费看久久久香蕉| 久久精品国产精品| 日韩亚洲一区在线播放| 久久精品视频免费观看| 亚洲婷婷免费| 日韩午夜高潮| 91久久在线视频| 国产午夜精品全部视频在线播放|