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

#ant

The dreams in which I'm dying are the best I've ever had...

從Win32 API封裝Thread類[1]

前幾天在學Windows多線程程序設計,發現Win32 API用起來確實不怎么方便,特別是對于C++程序員。于是實現了一個簡單的封裝,技術含量當然不高,不過用起來還是比較方便的。如果你熟悉Java,你會發現這個實現有點像Java的Thread,在Java中有兩種方法可以創建一個Thread:

1.從Thread類繼承并實現run方法:

1?class?MyThread?extends ?Thread?{
2?????public?void
?run()?{
3?
????????...
4?
????}?
5?
};
6?

7?//開啟線程
8?MyThread?thread?=?new ?MyThread;
9?thread.start();

2.聲明一個類實現Runnable接口并實現run方法:

1?class?MyRunnable?implements ?Runnable?{
2?????public?void
?run()?{
3?
????????...
4?
????}
5?
};
6?

7?//?開啟線程?
8?MyThread?thread?=?new?MyThread(new ?MyRunnable);
9?thread.start();


具體實現
Java的實現方式還算優雅,我們也可以在C++中模擬,由于篇幅所限,在這里我們只關注基本功能的實現:
thread.h
?1?#ifndef?THREAD_H
?2?
#define?THREAD_H
?3?

?4?#include?<windows.h>
?5?
?6?#define?CLASS_UNCOPYABLE(classname)?\
?7?????private
:?\
?8?????classname(const?classname&
);?\
?9?????classname&?operator=(const?classname&
);
10?

11?struct?Runnable?{
12?????virtual?void?run()?=?0
;
13?????virtual?~
Runnable()?{}
14?
};
15?

16?class?Thread?:?public?Runnable?{
17?
????CLASS_UNCOPYABLE(Thread)
18?public
:
19?????explicit?Thread(Runnable* target?=?0
);
20?????virtual?~
Thread();
21?????virtual?void
?run()?{}
22?????void
?start();
23?????void
?join();
24?private
:
25?????static?unsigned?__stdcall?threadProc(void*
param);
26?private
:
27?????Runnable*
_target;
28?
????HANDLE?_handle;
29?
};
30?

31?#endif/*THREAD_H*/

在上面的代碼中我們先定義一個Runnable類,并為Runnable類添加純虛函數run,需要特別注意的是Runnable類的虛析構函數,任何想要成為基類的class都應該聲明析構函數為virtual。
Thread類直接繼承自Runnable,CLASS_UNCOPYABLE(Thread) 這一行用宏聲明Thread類不可拷貝,具體細節請看 考慮用Macro替換Uncopyable 。start成員函數和Java中的一樣,用來開啟一個線程,join成員函數用來阻塞當前線程直到開啟的線程執行完畢。threadProc作為靜態成員函數用來傳遞給_beginthreadex,至于為什么用_beginthreadex代替CreateThread請問Google。初步的實現都比較簡單,直接貼上代碼:
thread.cpp
?1?#include?"thread.h"
?2?#include?<process.h>?// for?_beginthreadex
?3?
?4?Thread::Thread(Runnable* target?/*=?0*/)
?5?:_target(target
)
?6?,_handle(0
)?{
?7?

?8?}
?9?

10?Thread::~Thread()?{
11?????if?(_handle?!=?0
)
12?
????????CloseHandle(_handle);
13?????if?(_target?!=?0
)
14?
????????delete?_target;
15?
}
16?

17?void?Thread::start()?{
18?????if?(_handle?!=?0
)
19?????????return
;
20?
????unsigned?id;
21?????_handle?=?reinterpret_cast<HANDLE>
(
22?????????_beginthreadex(0,?0,?threadProc,?this,?0,?&
id)
23?
????????);
24?
}
25?

26?void?Thread::join()?{
27?????if(_handle?!=?0
)?{
28?
????????WaitForSingleObject(_handle,?INFINITE);
29?
????????CloseHandle(_handle);
30?????????_handle?=?0
;
31?
????}
32?
}
33?

34?unsigned?__stdcall?Thread::threadProc(void* param)?{
35?????Thread* p?=?static_cast<Thread*>
(param);
36?????if?(p->_target?!=?0
)
37?????????p->_target->
run();
38?????else

39?????????p->run();
40?????return?0
;
41?}

下面是測試代碼:
test.cpp
?1?#include?"thread.h"
?2?#include?<iostream>
?3?
?4?using?namespace?std;
?5?

?6?//第一種方法,從Thread類繼承
?7?struct?MyThread?:?public?Thread?{
?8?????virtual?void
?run()?{
?9?????????for?(int?i?=?0;?i?<?5;?++
i)?{
10?????????????cout?<<?"MyThread?Running..."?<<?i?<<
?endl;
11?????????????Sleep(100
);
12?
????????}
13?
????}
14?
};
15?

16?//第二種方法,“實現”Runnable接口
17?struct?MyRunnable?:?public?Runnable?{
18?????virtual?void
?run()?{
19?????????for?(int?i?=?0;?i?<?5;?++
i)?{
20?????????????cout?<<?"MyRunnable?Running..."?<<?i?<<
?endl;
21?????????????Sleep(300
);
22?
????????}
23?
????}
24?
};
25?

26?int?main()?{
27?

28?????MyThread?thread1;
29?????Thread?thread2(new
?MyRunnable());
30?
????thread1.start();
31?
????thread2.start();
32?
????thread1.join();
33?
????thread2.join();
34?

35?????return?0;
36?}

可能的運行結果:
MyThread Running...0
MyRunnable Running...0
MyThread Running...1
MyThread Running...2
MyRunnable Running...1
MyThread Running...3
MyThread Running...4
MyRunnable Running...2
MyRunnable Running...3
MyRunnable Running...4


如果你熟悉boost庫,你會知道boost庫的Thread構造函數可以接受普通函數和函數對象作為參數,如果你覺得從Thread類繼承或者實現Runnable接口還不夠簡潔,下一篇會有一個比較好的改進。

posted on 2007-08-30 10:18 螞蟻終結者 閱讀(4636) 評論(8)  編輯 收藏 引用 所屬分類: C++

Feedback

# re: 從Win32 API封裝Thread類[1] 2007-08-31 15:18 重劍

受益匪淺啊   回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-02-26 17:51 sd

太簡單了  回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-07-25 22:46 Robinfoxnan

看了樓主的TEA,和strlen覺得分析的很好,
但是,關于多線程,
在侯捷的《windows多線程程序設計》中說,建議不使用_beginthreadex之類純API函數,原因是在使用了線程本地存儲的函數,比如GetLastError()之類的函數后,運行庫比如VC++,會幫你建立一些我們看不到的結構體,會容易導致內存泄露,建議使用AfxBeginThread()類,特定開發環境提供的函數或者類,比如CWinThread。
可以參考該書第8章!  回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-10-10 01:23 OwnWaterloo

@Robinfoxnan
我幫樓主回你了 ~~

侯捷的書, 肯定說的是不要使用 CreateTread 這個API
如果他說的是不要使用 _beginthreadex , 那他該被拖出去打。

至于AfxBeginThread ,windows平臺下寫程序一定要和MFC扯上關系么?

既然你提到了AfxBeginThread, 你可以去看一下MFC的源碼, MFC80, 它就是使用的 _beginthreadex ~~

  回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-10-10 01:36 OwnWaterloo

我有2個建議, 一個可以慎重考慮一下, 另外一個可以完全不理睬。
還有2個疑問 ……

1.單下劃線開始的標識符?

2.將windows.h 從thread.h中移走
.h
class Thread {
//
private:
uintptr_t handle_;
}

.cpp
handle_ = _beginthreadex 這個可以直接賦值
CloseHandle( reinterpret_cast<HANDLE>( handle_ ); 這個要自己轉
雖然麻煩一點, 但是將 windows.h 隔離到了頭文件之外




疑問:
1. Thread的析構

10 Thread::~Thread() {
11 if (_handle != 0)
12 CloseHandle(_handle);
13 if (_target != 0)
14 delete _target;
15 }

CloseHandle 線程并不停止
如果主線程沒有join delete _target; 后 線程還在run

這是線程函數
34 unsigned __stdcall Thread::threadProc(void *param) {
35 Thread *p = static_cast<Thread*>(param);
36 if (p->_target != 0)
37 p->_target->run();
38 else
39 p->run();
40 return 0;
41 }

37 行, 如果被delete, 而且run訪問了數據, 而不僅僅是打印一些console消息, 肯定會引發錯誤。


疑問是: join 是慣例? 規范? 還是僅僅是boost的示例而已。


2.Thread 似乎并不需要從 Runable 繼承。
完全可以設計成 Thread是Runable的容器。

疑問是: 僅僅是為了模仿Java的行為?
  回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-10-10 09:15 螞蟻終結者

@Robinfoxnan
OwnWaterloo回答的也是我想回答的,我就不多說了。  回復  更多評論   

# re: 從Win32 API封裝Thread類[1] 2008-10-10 09:35 螞蟻終結者

@OwnWaterloo
建議:
1.單下劃線開始的標識符?
這個是編程風格問題,很難說出哪個更好哪個更差,正所謂蘿卜白菜各有所愛,個人認為成員變量無論是下劃線開始(如:_handle)還是下劃線結尾(如:handle_),又或者是用匈牙利命名法,只要在編碼中始終保持一種風格就好。編碼風格對程序員來說可能是一種信仰。

2.將windows.h 從thread.h中移走
這個確實是可以考慮,如果考慮到跨平臺的話。

疑問:
1. Thread的析構
據我所知,join應該是等待線程結束的慣用法,Java.Thread,boost.Thread都通過join來保證線程的安全結束。是否是規范我也不清楚,貌似join是POSIX中線程取消規范中的一個?

2.Thread 似乎并不需要從 Runable 繼承
是不需要繼承Runnable的,這樣只是模仿Java的行為。
  回復  更多評論   

# re: 從Win32 API封裝Thread類[1][未登錄] 2013-06-08 17:19 Jackie

這里有個問題, 是 如果你沒有join的話, 線程對象就會被馬上析構, 程序出現崩潰.
所以我把線程對象創建在堆上面了, 然后在Run調用完之后在threadProc里面delete 完成  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            99在线精品视频| 在线观看国产日韩| 久久精品理论片| 一区二区三区高清在线| 亚洲人成网站在线观看播放| 蜜臀久久99精品久久久久久9| 久久久国产精品一区| 久久精品72免费观看| 久久精品国产免费| 蜜桃伊人久久| 欧美福利精品| 日韩视频在线永久播放| 亚洲先锋成人| 午夜日韩福利| 免费黄网站欧美| 欧美三日本三级三级在线播放| 国产精品久久久久一区| 国产一区二区三区日韩欧美| 1024欧美极品| 午夜精品久久久久久99热软件| 美女脱光内衣内裤视频久久影院| 蜜臀av在线播放一区二区三区| 亚洲一区二区在线看| 久久九九热re6这里有精品| 欧美国产日韩一区| 国产日本亚洲高清| 亚洲三级影院| 久久精品国产亚洲aⅴ| 亚洲国产成人精品久久久国产成人一区| 亚洲精品影视| 老牛嫩草一区二区三区日本| 国产精品丝袜久久久久久app| 亚洲人在线视频| 久久国产精品色婷婷| 亚洲美女色禁图| 麻豆精品传媒视频| 国产一区二区三区直播精品电影| 亚洲天堂av在线免费| 亚洲国产1区| 久久九九国产精品| 国产毛片久久| 午夜精品久久久99热福利| 亚洲国产精品久久人人爱蜜臀| 欧美一区二区三区四区高清| 欧美色视频日本高清在线观看| 亚洲国产欧美日韩另类综合| 久久综合九色综合欧美就去吻| 亚洲深夜影院| 欧美视频一区在线| 一区二区国产日产| 亚洲品质自拍| 欧美高清视频免费观看| 亚洲高清影视| 欧美freesex交免费视频| 欧美在线免费一级片| 国产精品午夜久久| 午夜在线视频一区二区区别| 妖精成人www高清在线观看| 欧美精品免费播放| 9色精品在线| 亚洲精品之草原avav久久| 免费成人性网站| 亚洲精品久久久久久下一站 | 亚洲视屏一区| 国产精品白丝黑袜喷水久久久| 99re6这里只有精品| 亚洲精品免费一区二区三区| 欧美多人爱爱视频网站| 亚洲精品国产精品国自产观看浪潮| 欧美成人久久| 欧美成人精品福利| 99精品国产高清一区二区| 亚洲精品影院| 国产精品美女www爽爽爽视频| 亚洲欧美日韩国产成人精品影院| 亚洲激情婷婷| 国产精品夫妻自拍| 欧美日韩国产精品一区| 国产精品女人毛片| 亚洲自拍都市欧美小说| 亚洲视频电影图片偷拍一区| 国产精品入口麻豆原神| 欧美亚洲视频在线观看| 久久成人18免费观看| 亚洲人体1000| 一区二区三区高清在线| 国产欧美激情| 欧美不卡视频一区| 国产精品电影在线观看| 久久在线免费观看视频| 欧美激情国产日韩| 欧美亚洲免费| 欧美顶级艳妇交换群宴| 午夜亚洲福利在线老司机| 久久精品视频在线播放| 一区二区av在线| 欧美一级午夜免费电影| 99re8这里有精品热视频免费 | 亚洲日本中文字幕区| 一区二区三区精品在线| 1000部国产精品成人观看| 夜久久久久久| 最新成人av网站| 99精品国产一区二区青青牛奶| 国产日韩在线视频| 欧美国产视频日韩| 国产日韩欧美另类| 亚洲国产综合在线看不卡| 国产精品美女久久| 亚洲精品乱码久久久久久蜜桃麻豆 | 久久久久久久综合| 亚洲淫性视频| 欧美成人国产| 久久这里只有精品视频首页| 欧美日韩三级视频| 亚洲第一色中文字幕| 国产综合婷婷| 亚洲自拍偷拍麻豆| 亚洲一区免费看| 欧美日韩国产三区| 亚洲黄网站在线观看| 精品成人免费| 久久国产福利| 欧美影院一区| 国产精品毛片a∨一区二区三区| 亚洲精品国产精品乱码不99 | 亚洲视频久久| 久久国产毛片| 欧美一区二区精品| 国产精品永久免费| 免费视频一区二区三区在线观看| 国产精品日韩欧美一区二区三区| 亚洲第一二三四五区| 在线观看欧美日本| 久久夜色精品国产噜噜av| 久久天天躁夜夜躁狠狠躁2022| 国产日韩av一区二区| 性感少妇一区| 久久亚洲春色中文字幕| 激情视频一区二区| 米奇777在线欧美播放| 亚洲电影第三页| 99热精品在线| 国产精品扒开腿做爽爽爽视频| 在线综合视频| 久久精品女人天堂| 亚洲国产婷婷香蕉久久久久久| 欧美成人蜜桃| 妖精成人www高清在线观看| 性欧美激情精品| 国内精品久久久久影院薰衣草| 久久久精品国产免费观看同学| 你懂的国产精品| 亚洲美女中文字幕| 国产精品美女在线| 午夜老司机精品| 欧美激情第4页| 亚洲欧美精品suv| 国内精品美女av在线播放| 老司机精品福利视频| 亚洲日本欧美日韩高观看| 亚洲一区二区在线| 国产亚洲a∨片在线观看| 老司机精品视频一区二区三区| 亚洲人午夜精品免费| 欧美呦呦网站| 日韩午夜电影av| 国产一区二区三区在线观看精品| 久久综合久久久久88| 一本色道久久综合亚洲精品婷婷 | 亚洲在线观看视频| 精品1区2区3区4区| 欧美视频在线观看一区二区| 久久久精品五月天| 亚洲精品影视| 久久影视三级福利片| 一本一本a久久| 在线看欧美视频| 国产精品久久综合| 欧美大片免费久久精品三p| 午夜精品av| 亚洲欧洲在线免费| 快she精品国产999| 欧美一区二区三区成人| 亚洲美女色禁图| 在线看片成人| 国产日韩欧美a| 欧美日韩亚洲一区二区三区| 久久人人爽爽爽人久久久| 亚洲欧美日韩一区在线| 亚洲精品一区二区三区99| 免费观看欧美在线视频的网站| 久久久久9999亚洲精品| 久久精品99国产精品| 国产区在线观看成人精品| 91久久精品国产91久久性色| 在线看日韩欧美| 久久精品夜色噜噜亚洲a∨| 一区二区日韩| 日韩一级大片在线|