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

#ant

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

從Win32 API封裝Thread類[1]

前幾天在學(xué)Windows多線程程序設(shè)計(jì),發(fā)現(xiàn)Win32 API用起來確實(shí)不怎么方便,特別是對(duì)于C++程序員。于是實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的封裝,技術(shù)含量當(dāng)然不高,不過用起來還是比較方便的。如果你熟悉Java,你會(huì)發(fā)現(xiàn)這個(gè)實(shí)現(xiàn)有點(diǎn)像Java的Thread,在Java中有兩種方法可以創(chuàng)建一個(gè)Thread:

1.從Thread類繼承并實(shí)現(xiàn)run方法:

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

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

2.聲明一個(gè)類實(shí)現(xiàn)Runnable接口并實(shí)現(xiàn)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();


具體實(shí)現(xiàn)
Java的實(shí)現(xiàn)方式還算優(yōu)雅,我們也可以在C++中模擬,由于篇幅所限,在這里我們只關(guān)注基本功能的實(shí)現(xiàn):
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*/

在上面的代碼中我們先定義一個(gè)Runnable類,并為Runnable類添加純虛函數(shù)run,需要特別注意的是Runnable類的虛析構(gòu)函數(shù),任何想要成為基類的class都應(yīng)該聲明析構(gòu)函數(shù)為virtual。
Thread類直接繼承自Runnable,CLASS_UNCOPYABLE(Thread) 這一行用宏聲明Thread類不可拷貝,具體細(xì)節(jié)請(qǐng)看 考慮用Macro替換Uncopyable 。start成員函數(shù)和Java中的一樣,用來開啟一個(gè)線程,join成員函數(shù)用來阻塞當(dāng)前線程直到開啟的線程執(zhí)行完畢。threadProc作為靜態(tài)成員函數(shù)用來傳遞給_beginthreadex,至于為什么用_beginthreadex代替CreateThread請(qǐng)問Google。初步的實(shí)現(xiàn)都比較簡(jiǎn)單,直接貼上代碼:
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?}

下面是測(cè)試代碼:
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?//第二種方法,“實(shí)現(xiàn)”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?}

可能的運(yùn)行結(jié)果:
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庫,你會(huì)知道boost庫的Thread構(gòu)造函數(shù)可以接受普通函數(shù)和函數(shù)對(duì)象作為參數(shù),如果你覺得從Thread類繼承或者實(shí)現(xiàn)Runnable接口還不夠簡(jiǎn)潔,下一篇會(huì)有一個(gè)比較好的改進(jìn)。

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

Feedback

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

受益匪淺啊   回復(fù)  更多評(píng)論   

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

太簡(jiǎn)單了  回復(fù)  更多評(píng)論   

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

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

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

@Robinfoxnan
我?guī)蜆侵骰啬懔?~~

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

至于AfxBeginThread ,windows平臺(tái)下寫程序一定要和MFC扯上關(guān)系么?

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

  回復(fù)  更多評(píng)論   

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

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

1.單下劃線開始的標(biāo)識(shí)符?

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

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




疑問:
1. Thread的析構(gòu)

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

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

這是線程函數(shù)
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訪問了數(shù)據(jù), 而不僅僅是打印一些console消息, 肯定會(huì)引發(fā)錯(cuò)誤。


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


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

疑問是: 僅僅是為了模仿Java的行為?
  回復(fù)  更多評(píng)論   

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

@Robinfoxnan
OwnWaterloo回答的也是我想回答的,我就不多說了。  回復(fù)  更多評(píng)論   

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

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

2.將windows.h 從thread.h中移走
這個(gè)確實(shí)是可以考慮,如果考慮到跨平臺(tái)的話。

疑問:
1. Thread的析構(gòu)
據(jù)我所知,join應(yīng)該是等待線程結(jié)束的慣用法,Java.Thread,boost.Thread都通過join來保證線程的安全結(jié)束。是否是規(guī)范我也不清楚,貌似join是POSIX中線程取消規(guī)范中的一個(gè)?

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

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

這里有個(gè)問題, 是 如果你沒有join的話, 線程對(duì)象就會(huì)被馬上析構(gòu), 程序出現(xiàn)崩潰.
所以我把線程對(duì)象創(chuàng)建在堆上面了, 然后在Run調(diào)用完之后在threadProc里面delete 完成  回復(fù)  更多評(píng)論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲国产一区二区三区a毛片| 一本大道久久精品懂色aⅴ| 亚洲欧美日韩国产一区| 亚洲裸体视频| 亚洲激情国产精品| 久久青青草综合| 久久―日本道色综合久久| 亚洲伊人伊色伊影伊综合网| 禁断一区二区三区在线| 国产精品久久国产愉拍| 欧美尤物巨大精品爽| 亚洲电影免费观看高清完整版| 欧美呦呦网站| 久久精品电影| 欧美成人黑人xx视频免费观看| 亚洲丝袜av一区| 欧美一区二区三区在线播放| 久久全国免费视频| 99re6热在线精品视频播放速度| 国产精品揄拍一区二区| 国产日韩欧美不卡在线| 国产欧美一区二区精品秋霞影院| 国产亚洲成av人在线观看导航| 欧美视频免费看| 国产精品每日更新| 亚洲精选大片| 老司机午夜精品| 国产精一区二区三区| 亚洲专区欧美专区| 欧美电影在线观看完整版| 国产精品日韩专区| 亚洲免费观看高清完整版在线观看熊| 亚洲欧美综合v| 亚洲精品久久久久中文字幕欢迎你| 中文日韩欧美| 欧美精品日韩一区| 国内精品免费午夜毛片| 中文精品视频| 欧美国产亚洲视频| 久久夜色精品国产噜噜av| 国产精品ⅴa在线观看h| 亚洲人线精品午夜| 国产精品久久久久久五月尺| 亚洲电影有码| 欧美激情一区| 久久久精品午夜少妇| 国产一区二区你懂的| 久久精品道一区二区三区| 欧美一区二区三区啪啪| 国产有码在线一区二区视频| 久久蜜桃av一区精品变态类天堂| 夜夜夜久久久| 国产精品羞羞答答| 亚洲精品一区二区在线| 国产麻豆9l精品三级站| 亚洲一区欧美| 亚洲欧美日韩国产精品| 亚洲国语精品自产拍在线观看| 欧美不卡一区| 欧美成人免费大片| 亚洲制服少妇| 久久久久一区二区三区| 亚洲人午夜精品| 在线一区亚洲| 日韩视频在线一区二区| 亚洲午夜国产一区99re久久| 国语对白精品一区二区| 亚洲精品视频二区| 在线电影国产精品| 亚洲自啪免费| 亚洲精品免费在线| 久久黄色小说| 羞羞答答国产精品www一本 | 农村妇女精品| 欧美一区二区三区免费视| 久久精品99国产精品日本| 欧美视频一区二区三区…| 久久久夜色精品亚洲| 欧美日韩精品免费观看视频完整 | 久久青青草综合| 亚洲欧美日韩在线观看a三区| 老司机一区二区三区| 欧美精品二区| 免费久久精品视频| 亚洲第一精品久久忘忧草社区| 欧美专区日韩专区| 久久视频在线看| 亚洲免费福利视频| 国产精品久久久久久久久搜平片| 9色porny自拍视频一区二区| 亚洲欧美日韩另类| 国产农村妇女毛片精品久久莱园子| 亚洲巨乳在线| 欧美在线二区| 亚洲盗摄视频| 国产精品二区二区三区| 性亚洲最疯狂xxxx高清| 久久久综合香蕉尹人综合网| 伊人久久噜噜噜躁狠狠躁| 欧美另类人妖| 久久av资源网| 亚洲成人在线网站| 欧美激情精品久久久久久大尺度| 亚洲国产经典视频| 欧美精选一区| 老色鬼精品视频在线观看播放| 亚洲成人资源| 美女91精品| 久久久国产精彩视频美女艺术照福利| 亚洲二区在线观看| 国产亚洲精品一区二555| 欧美激情视频一区二区三区在线播放| 夜夜嗨网站十八久久| 国产一区二区三区av电影| 欧美极品色图| 久久久久久久高潮| 久久精品中文字幕一区| 亚洲女性喷水在线观看一区| 亚洲国产高清高潮精品美女| 久久久av毛片精品| 久久午夜精品| 久久中文字幕导航| 久热精品视频在线免费观看| 久久嫩草精品久久久精品一| 久久国产精品久久久| 久久高清免费观看| 亚欧成人精品| 亚洲欧洲日韩在线| 亚洲免费观看高清完整版在线观看熊 | 欧美国产在线电影| 欧美成人一二三| 亚洲精品在线观看免费| 一区二区激情视频| 性欧美大战久久久久久久免费观看 | 亚洲视频在线一区观看| 欧美日韩精品国产| 久久激情五月丁香伊人| 亚洲免费影视第一页| 亚洲欧美国产77777| 久久精品国产77777蜜臀| 亚洲视频一区二区免费在线观看| 国产精品一区久久久久| 欧美精品在线观看91| 欧美日一区二区在线观看| 久久综合网hezyo| 亚洲国产精品电影在线观看| 亚洲美女91| 欧美日韩亚洲综合在线| 鲁大师影院一区二区三区| 香蕉成人伊视频在线观看| 亚洲午夜精品在线| 欧美一区二区| 欧美午夜一区二区福利视频| 欧美高清视频一区二区| 欧美天堂亚洲电影院在线播放| 亚洲激情六月丁香| 欧美日韩国产成人在线观看| 亚洲欧洲日本在线| 一区二区三区蜜桃网| 在线观看精品视频| 欧美国产在线观看| 欧美一区二区日韩一区二区| 国内视频精品| 在线中文字幕一区| 欧美午夜不卡在线观看免费 | 久久久噜噜噜久久中文字免| 久久久久久亚洲综合影院红桃 | 国产欧美日韩综合| 久久综合久久久| 午夜精品成人在线| 欧美刺激午夜性久久久久久久| 欧美91大片| 亚洲欧美偷拍卡通变态| 男女精品视频| 亚洲国产日韩在线一区模特| 亚洲伊人观看| 日韩一级黄色片| 久久久九九九九| 日韩午夜电影av| 国产一区二区三区精品久久久 | 亚洲综合色激情五月| 亚洲制服av| 亚洲无限乱码一二三四麻| 麻豆精品在线视频| 欧美一区午夜精品| 国产精品电影观看| 美国十次了思思久久精品导航| 欧美一区二区三区在线| 免播放器亚洲一区| 快播亚洲色图| 久久国产精品免费一区| 91久久极品少妇xxxxⅹ软件| 国外成人在线| 亚洲免费在线视频一区 二区| 国产午夜精品久久| 亚洲一区二区三区免费观看 | 国产精品欧美一区二区三区奶水| 久久久久五月天| 浪潮色综合久久天堂| 亚洲成人自拍视频|