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

隨筆 - 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>
              久久av一区二区三区| 国产精品99久久99久久久二8| 欧美一区二区三区久久精品| 欧美色图一区二区三区| 亚洲一区二区在| 亚洲视频www| 国产一区二区三区高清| 毛片一区二区| 美女亚洲精品| 久久综合伊人77777| 另类人畜视频在线| avtt综合网| 性欧美精品高清| 亚洲电影下载| 夜夜爽www精品| 国外成人在线视频| 91久久久久| 国产日韩欧美精品在线| 蜜桃久久av| 欧美日韩一区二区三区四区在线观看| 欧美在线综合视频| 蜜臀久久99精品久久久久久9 | 亚洲欧美国产精品专区久久| 午夜在线精品| 日韩视频在线一区二区| 午夜欧美理论片| 亚洲精品一二区| 亚洲欧美电影在线观看| 亚洲人成小说网站色在线| 亚洲一区二区三区免费在线观看| 狠狠色丁香婷婷综合| 99riav久久精品riav| 激情综合久久| 一区二区三区国产精华| 亚洲成色www8888| 亚洲综合国产| 一区二区三区精品| 欧美777四色影视在线| 久久精品中文字幕一区| 欧美日韩黄色大片| 欧美国产亚洲精品久久久8v| 国产日韩精品久久久| 亚洲人永久免费| 亚洲福利视频免费观看| 欧美一区二区三区四区高清| 亚洲一区日韩在线| 欧美久久影院| 欧美激情亚洲国产| 一区在线观看视频| 午夜一区二区三区不卡视频| 午夜精品美女自拍福到在线| 欧美日本精品| 亚洲人精品午夜| 91久久国产综合久久91精品网站| 欧美在线免费观看亚洲| 欧美一区三区二区在线观看| 国产精品都在这里| 一本综合精品| 亚洲一区二区视频| 欧美三级日韩三级国产三级| 亚洲三级影院| 一区二区三区免费在线观看| 欧美日韩1区| 亚洲人妖在线| 亚洲一级二级| 国产精品免费观看在线| 亚洲视频中文字幕| 午夜影视日本亚洲欧洲精品| 国产精品入口福利| 欧美一区二区啪啪| 国产一区二区三区奇米久涩| 欧美一区免费视频| 中文国产成人精品| 国产精品久久久久国产精品日日| 亚洲无限av看| 久久精品国产77777蜜臀| 国产综合一区二区| 老司机免费视频一区二区| 欧美第一黄网免费网站| 亚洲国产精品久久久久秋霞蜜臀| 噜噜噜91成人网| 91久久精品国产91性色| 亚洲图片欧洲图片日韩av| 国产精品日韩欧美大师| 久久久久久久久久久久久9999| 欧美国产专区| 亚洲一区三区视频在线观看| 国产欧美在线观看| 蜜乳av另类精品一区二区| 亚洲精品小视频| 久久成人一区二区| 亚洲茄子视频| 国产欧美va欧美va香蕉在| 久久久久国色av免费观看性色| 亚洲国产天堂网精品网站| 亚洲欧美综合另类中字| 在线日本成人| 国产精品乱码一区二三区小蝌蚪| 亚洲欧美一区二区三区久久| 欧美韩日一区二区| 香蕉av福利精品导航| 最新中文字幕亚洲| 国产欧美日韩一区二区三区在线 | 一区二区国产在线观看| 久久亚洲欧美| 亚洲一区二区三区精品在线| 亚洲国产成人tv| 国产精品嫩草99a| 欧美成人69av| 久久动漫亚洲| 在线视频一区二区| 亚洲国产精品999| 久久黄金**| 亚洲在线视频观看| 91久久精品美女高潮| 国产区欧美区日韩区| 欧美日韩在线另类| 欧美jizz19性欧美| 久久久久久久久久久一区| 午夜精品久久久久久久久久久久久 | 久久九九全国免费精品观看| 中日韩高清电影网| 亚洲国产日本| 能在线观看的日韩av| 久久九九99视频| 欧美一区二区三区四区在线| 亚洲一区国产| 中文亚洲字幕| 一区二区高清视频在线观看| 亚洲国产一区二区三区青草影视 | 国产精品自拍视频| 欧美三级视频| 欧美日韩在线高清| 欧美三级韩国三级日本三斤| 欧美日本一区二区视频在线观看| 久久综合五月天婷婷伊人| 欧美成熟视频| 国产精品大全| 国产精品劲爆视频| 欧美天天影院| 欧美视频一区二区三区四区| 欧美日本精品在线| 欧美揉bbbbb揉bbbbb| 欧美三级第一页| 国产精品高潮粉嫩av| 国产精品a久久久久| 欧美色精品天天在线观看视频| 欧美日韩亚洲视频| 欧美视频免费| 国产精品一区二区久久久| 国产精品欧美在线| 国产女人18毛片水18精品| 国产女人精品视频| 国产一区二区剧情av在线| 国产一区视频在线观看免费| 极品日韩久久| 亚洲精选久久| 亚洲一区二区三区中文字幕| 午夜精品一区二区三区在线| 欧美伊人久久久久久午夜久久久久| 久久国产精品一区二区| 美女性感视频久久久| 亚洲黄色免费| 亚洲桃色在线一区| 久久成人精品无人区| 久久亚洲风情| 欧美日韩在线精品| 国产日韩欧美精品在线| 亚洲电影免费观看高清完整版在线观看 | 欧美激情精品久久久久久免费印度 | 欧美激情一区二区三区四区 | 欧美激情第1页| 国产精品久久久久久久久久久久久| 国产日韩欧美精品综合| 亚洲国产日韩综合一区| 亚洲视频第一页| 久久精品日产第一区二区三区| 亚洲福利国产精品| 亚洲一区国产| 欧美成人高清视频| 国产麻豆一精品一av一免费| 在线欧美日韩国产| 亚洲一区自拍| 亚洲二区视频在线| 午夜精品理论片| 欧美激情1区2区3区| 国内外成人免费视频| 一区二区三区|亚洲午夜| 久久亚洲欧美| 亚洲女人天堂av| 欧美日本精品| 亚洲日本久久| 久久久一本精品99久久精品66| 99视频在线观看一区三区| 久久久一区二区三区| 国产精品一区二区三区观看| 日韩一区二区久久| 免费观看久久久4p| 性视频1819p久久| 国产精品久久久|