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

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

常用鏈接

留言簿(5)

隨筆分類(38)

隨筆檔案(31)

收藏夾(4)

College

High School

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 56937
  • 排名 - 407

最新評論

  • 1.?re: [yc]詳解link
  • 面試的時候面試官就問過我什么是編譯和鏈接,我說編譯就是把代碼文件生成目標文件,鏈接就是把目標文件生成可執(zhí)行文件,他說不對,又問我什么是動態(tài)鏈接,還問我預編譯都做什么處理。。。都在這里找到了答案!!!!
  • --王至乾
  • 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 保存當前堆棧,選擇一個新的線程之后用 longjmp 跳轉(zhuǎn)過去。

 

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

 

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

 

問題:切換線程的時候, longjmp 不會恢復通用寄存器的值,因此要么函數(shù)內(nèi)的局部變量都加上 volatile ,要么在 setjmp 之前手動保存, longjmp 之后手動恢復(可以在庫的實現(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 閱讀(3355) 評論(4)  編輯 收藏 引用 所屬分類: C++

FeedBack:
# re: 用戶態(tài)非搶占式線程庫實現(xiàn) 2007-03-16 23:44 pluskid
哦?是在每個線程里面都要收工調(diào)用 schedule() 函數(shù)來切換線程的嗎?  回復  更多評論
  
# re: 用戶態(tài)非搶占式線程庫實現(xiàn) 2007-03-17 02:52 Francis Arcanum
@pluskid
是的  回復  更多評論
  
# re: [yc]用戶態(tài)非搶占式線程庫實現(xiàn) 2007-05-08 11:25 Rhythm
我想不通……一個用來貼代碼的blog系統(tǒng),代碼本身為啥不是等寬字體?  回復  更多評論
  
# re: [yc]用戶態(tài)非搶占式線程庫實現(xiàn) 2007-05-08 14:12 Francis Arcanum
@Rhythm
我錯了,貌似是我沒選擇字體。。。  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              欧美视频专区一二在线观看| 日韩视频一区二区三区在线播放| 黄色日韩网站视频| 欧美日韩在线观看一区二区三区| 一区二区日韩精品| 亚洲日本中文字幕区| 欧美77777| 欧美高清视频www夜色资源网| 久久久久久久久久看片| 一区二区三区久久精品| 亚洲三级国产| 99在线精品免费视频九九视| 亚洲理论在线| 亚洲欧美国产精品专区久久| 欧美亚洲一区二区三区| 欧美亚洲一区二区在线| 久久精品人人做人人爽电影蜜月| 亚洲综合精品| 久久精品国产欧美激情| 免费亚洲一区二区| 99精品视频免费观看| 亚洲在线免费观看| 久久综合色婷婷| 国产精品jvid在线观看蜜臀| 国产区在线观看成人精品| 亚洲电影在线| 9l国产精品久久久久麻豆| 亚洲欧美另类久久久精品2019| 欧美影院久久久| 亚洲破处大片| 欧美在线3区| 欧美精品在欧美一区二区少妇| 国产精品美女在线观看| 亚洲高清在线视频| 久久aⅴ乱码一区二区三区| 亚洲国内在线| 久久大逼视频| 国产综合香蕉五月婷在线| 这里只有精品视频| 亚洲国产高潮在线观看| 久久精品在这里| 国产自产v一区二区三区c| 欧美日韩在线观看一区二区| 欧美日韩一区国产| 欧美精品久久99| 国产日韩精品一区二区| 先锋影音久久| 欧美一区影院| 国产在线不卡| 亚洲大胆av| 欧美丝袜一区二区| 久久中文在线| 欧美亚一区二区| 免费成人美女女| 国产精品国产三级国产aⅴ无密码| 亚洲自拍三区| 麻豆成人综合网| 亚洲女女做受ⅹxx高潮| 久久综合免费视频影院| 亚洲欧美日韩国产中文在线| 久久久久久久久久看片| 亚洲欧美另类国产| 欧美精品自拍| 欧美福利视频一区| 国内精品美女在线观看| 99v久久综合狠狠综合久久| 在线观看一区视频| 午夜精品视频网站| 香港久久久电影| 国产精品高清网站| 一区二区三区产品免费精品久久75 | 欧美激情亚洲综合一区| 久久精品青青大伊人av| 国产精品久久| 欧美亚洲午夜视频在线观看| 午夜精品免费视频| 国产精品久久国产精品99gif| 蜜桃av一区二区三区| 伊人久久综合| 久久亚洲美女| 亚洲精品久久久久久久久| 亚洲欧洲在线播放| 欧美国产精品中文字幕| 亚洲国内高清视频| 亚洲一级影院| 国产视频一区二区三区在线观看| 亚洲在线电影| 欧美高清视频在线| 一二三区精品| 国产亚洲精品激情久久| 欧美高清在线| 亚洲一级片在线观看| 老司机一区二区三区| 一区二区精品| 亚洲高清色综合| 欧美精品一区二区三| 亚洲综合日韩| 9色porny自拍视频一区二区| 狂野欧美一区| 午夜亚洲视频| 亚洲另类自拍| 在线不卡中文字幕| 国产区精品视频| 欧美日韩精品福利| 久久精品91| 亚洲免费伊人电影在线观看av| 亚洲国产精品传媒在线观看| 女仆av观看一区| 久久久久国产精品www| 在线综合+亚洲+欧美中文字幕| 136国产福利精品导航| 黄色综合网站| 亚洲国产你懂的| 亚洲精品一区二区三| 欧美专区亚洲专区| 久久久久久久尹人综合网亚洲| 欧美一区二区高清| 久久免费精品视频| 久久露脸国产精品| 另类天堂av| 欧美日韩午夜在线| 国产精品免费网站| 国产日韩在线一区二区三区| 国语自产在线不卡| 亚洲国产乱码最新视频| 99精品国产在热久久| 午夜精品亚洲一区二区三区嫩草| 亚洲伊人一本大道中文字幕| 亚洲欧美一区二区三区极速播放 | 国产精品久久久久久一区二区三区| 欧美电影免费| 国产精品视频大全| 亚洲激情校园春色| 午夜精品在线视频| 久久一二三四| 国产精品99久久久久久白浆小说 | 国产精品视频1区| 影音先锋亚洲一区| 午夜视频一区在线观看| 亚洲黄色精品| 久久久亚洲综合| 国产一二精品视频| 欧美一级一区| 亚洲一区二区精品| 欧美色网在线| 午夜精品久久| 亚洲精品视频在线看| 欧美精品一区二区久久婷婷| 伊人成年综合电影网| 久久久久久久999精品视频| 日韩亚洲欧美高清| 久久久久久一区二区| 性欧美video另类hd性玩具| 国产精品丝袜91| 午夜视频在线观看一区二区| 亚洲一区一卡| 国产午夜精品美女视频明星a级| 欧美在线观看www| 亚洲性色视频| 国内精品国产成人| 亚洲电影在线观看| 欧美成人中文| 先锋影音网一区二区| 欧美一区二区高清在线观看| 亚洲美洲欧洲综合国产一区| 亚洲欧美国产高清va在线播| 久久久久久精| 欧美午夜影院| 亚洲第一中文字幕| 日韩午夜在线电影| 欧美在线视频免费| 欧美大胆a视频| 亚洲欧洲午夜| 亚洲欧洲精品成人久久奇米网| 欧美高清在线| 一区二区91| 久久久精品免费视频| 依依成人综合视频| 99综合在线| 亚洲国产精品久久久| 久久婷婷麻豆| 国产精品香蕉在线观看| 亚洲欧洲三级| 香蕉久久夜色精品国产使用方法| 久久综合电影| 国产欧美日韩在线视频| 夜久久久久久| 免费欧美网站| 亚洲女优在线| 欧美激情按摩| 国产精品久久久久aaaa九色| 国产精品乱人伦一区二区| 亚洲美女中出| 亚洲第一福利视频| 久久久久久久激情视频| 亚洲伦理自拍| 欧美日韩一区二区三区在线视频| 亚洲精品中文字幕有码专区| 亚洲精品一区二区三区在线观看| 久久精品一区二区三区四区|