网络服务器软件开发/中间件开发,关注ACE/ICE/boost
C++博客
首页
新随笔
联系
聚合
管理
152 Posts :: 3 Stories :: 172 Comments :: 0 Trackbacks
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(18)
给我留言
查看公开留言
查看私人留言
随笔分类
ACE(12)
boost(6)
C++基础(20)
CORBA(4)
Design Pattern(1)
ebook(1)
ICE(7)
java(1)
linux(28)
mysql(15)
PHP(1)
python(6)
RakNet(1)
SQLite
STL(1)
VC/MFC/.NET(4)
办公技巧(5)
编码知识(8)
创意&想法(2)
开发感想(12)
理财(2)
其它开源库(13)
生活感想(23)
数据结构算法(1)
通信技术(8)
网络服务器开发(9)
游戏开发(4)
随笔档案
2012年7月 (1)
2011年9月 (1)
2011年8月 (1)
2011年5月 (2)
2011年4月 (1)
2011年1月 (9)
2010年12月 (6)
2010年11月 (1)
2010年10月 (3)
2010年9月 (12)
2010年8月 (7)
2010年7月 (1)
2009年10月 (2)
2009年9月 (3)
2009年8月 (1)
2009年3月 (1)
2009年2月 (5)
2009年1月 (6)
2008年12月 (2)
2008年11月 (1)
2008年10月 (1)
2008年9月 (1)
2008年7月 (9)
2008年6月 (10)
2008年5月 (13)
2008年4月 (2)
2008年3月 (3)
2008年1月 (1)
2007年11月 (5)
2007年9月 (1)
2007年8月 (5)
2007年7月 (3)
2007年6月 (2)
2007年5月 (4)
2007年4月 (20)
2007年3月 (6)
文章分类
设计模式
文章档案
2007年3月 (3)
好友博客
LOGOS
搜索
积分与排名
积分 - 233235
排名 - 108
最新评论
1. re: C++实现的MD5算法
你这代码功底也够烂了,你多测试几次,内存哗哗的流...
--热心网页
2. re: std::queue的front的问题[未登录]
在c++中int并不是类,没有析构,是值拷贝。
你换std::string试试,准挂。
--星爷
3. re: mysql下如何执行sql脚本【转】[未登录]
Thanks!
--me
4. re: ldconfig几个需要注意的地方 zhuan
学习了,收藏
--thebye85
5. re: 体验RakNet的RPC3
评论内容较长,点击标题查看
--雅歌
阅读排行榜
1. mysql下如何执行sql脚本【转】(14967)
2. 怪异的boost,fatal error LNK1104: 无法打开文件“libboost_system-vc80-mt-gd-1_35.lib”(11396)
3. boost interprocess之message queue(7055)
4. 【ZT】ADSL大型技术专题(图文)(6894)
5. VOIP开源项目源码地址(二) ---[voip涉及到的所有的资料]【转帖】(5422)
评论排行榜
1. Buffer类就应该简单,直观(16)
2. 怪异的boost,fatal error LNK1104: 无法打开文件“libboost_system-vc80-mt-gd-1_35.lib”(13)
3. 自己造的一个线程类(12)
4. 对基本类型的再包装,方便了移植(12)
5. 游戏害惨了我多少同学(10)
自己造的一个线程类
#ifndef THREAD_H
#define
THREAD_H
#include
<
stdio.h
>
//
printf
#ifdef WIN32
#define
WIN32_LEAN_AND_MEAN
#include
<
Windows.h
>
#define
THREAD_API DWORD WINAPI
#else
#include
<
pthread.h
>
#define
THREAD_API void*
#endif
class
CThread
{
private
:
#ifdef WIN32
HANDLE m_hThreadHandle;
DWORD m_dwThreadId;
#else
pthread_t m_dwThreadId;
#endif
bool
m_bStopFlag;
//
是否已经“取消”该线程
bool
m_bStarted;
//
线程已经启动
private
:
struct
CThreadArg
{
CThread
*
m_pThread;
//
保存this指针
void
*
m_pArg;
//
保存start成员函数里面的arg参数指针
}
;
CThreadArg
*
m_pThrArg;
public
:
CThread();
~
CThread();
int
Start(
void
*
arg
=
NULL);
int
Wait();
//
成功返回0;失败-1
void
Terminate(
void
);
//
强制退出
void
SetStopFlag();
//
协作性退出
bool
GetStopFlag();
unsigned
int
GetID(
void
);
protected
:
void
SetThreadArg(CThreadArg
*
pThrArg
=
NULL);
CThreadArg
*
GetThreadArg(
void
);
virtual
void
Run(
void
*
arg)
=
0
;
//
1.子类重载此函数,在run里面完成所有功能.2.子类要检查GetStopFlag(),以配合对该线程的“停止”;或者采用强制终止Terminate()
private
:
static
THREAD_API Routine(
void
*
arg);
}
;
#endif
下面是Thread.cpp
#include
"
Thread.h
"
CThread::CThread():m_dwThreadId(
0
),m_bStopFlag(
false
),m_bStarted(
false
)
{
#ifdef WIN32
m_hThreadHandle
=
NULL;
SetThreadArg(NULL);
#endif
}
CThread::
~
CThread()
{
#ifdef WIN32
if
(m_hThreadHandle
!=
NULL)
{
CloseHandle(m_hThreadHandle);
}
#endif
if
(m_pThrArg
!=
NULL)
{
delete m_pThrArg;
m_pThrArg
=
NULL;
}
}
int
CThread::Start(
void
*
arg
/**/
/*
= NULL
*/
)
{
if
(m_bStarted)
{
return
0
;
}
else
{
m_bStarted
=
true
;
}
CThreadArg
*
pThrArg
=
new
CThreadArg();
pThrArg
->
m_pArg
=
arg;
pThrArg
->
m_pThread
=
this
;
#ifdef WIN32
m_hThreadHandle
=
CreateThread(NULL,NULL,Routine,(
void
*
)pThrArg,NULL,
&
m_dwThreadId);
if
(m_hThreadHandle
!=
NULL)
{
m_pThrArg
=
pThrArg;
return
0
;
}
else
{
delete pThrArg;
return
-
1
;
}
#else
int
ret
=
pthread_create(
&
m_dwThreadId,NULL,Routine,(
void
*
)pThrArg);
if
(ret
==
0
)
{
m_pThrArg
=
pThrArg;
return
0
;
}
else
{
delete pThrArg;
return
-
1
;
}
#endif
}
int
CThread::Wait()
{
#ifdef WIN32
::WaitForSingleObject(m_hThreadHandle,INFINITE);
BOOL bRet
=
CloseHandle(m_hThreadHandle);
if
(bRet)
{
m_hThreadHandle
=
NULL;
return
0
;
}
else
return
-
1
;
#else
int
nRet
=
pthread_join(m_dwThreadId,NULL);
if
(nRet
==
0
)
return
0
;
else
return
-
1
;
#endif
}
void
CThread::SetStopFlag()
{
m_bStopFlag
=
true
;
return
;
}
bool
CThread::GetStopFlag()
{
return
m_bStopFlag;
}
void
CThread::Terminate()
{
#ifdef WIN32
if
(GetCurrentThreadId()
==
m_dwThreadId)
{
ExitThread(
0
);
return
;
}
else
{
TerminateThread(m_hThreadHandle,
0
);
DWORD dwRet
=
0
;
GetExitCodeThread(m_hThreadHandle,
&
dwRet);
while
(dwRet
==
STILL_ACTIVE)
{
printf(
"
still active \n
"
);
Sleep(
100
);
TerminateThread(m_hThreadHandle,
0
);
GetExitCodeThread(m_hThreadHandle,
&
dwRet);
}
}
#else
if
(pthread_self()
==
m_dwThreadId)
{
pthread_exit(NULL);
return
;
}
else
{
pthread_cancel(m_dwThreadId);
}
#endif
SetStopFlag();
return
;
}
unsigned
int
CThread::GetID(
void
)
{
return
(unsigned
int
) m_dwThreadId;
}
void
CThread::SetThreadArg(CThreadArg
*
pThrArg
/**/
/*
= NULL
*/
)
{
m_pThrArg
=
pThrArg;
return
;
}
CThread::CThreadArg
*
CThread::GetThreadArg()
{
return
m_pThrArg;
}
THREAD_API CThread::Routine(
void
*
arg)
{
CThreadArg
*
pThrArg
=
(CThreadArg
*
)arg;
#ifndef WIN32
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
#endif
pThrArg
->
m_pThread
->
Run(pThrArg
->
m_pArg);
return
NULL;
}
自己用的,如果你有好的想法,告诉我!
posted on 2009-01-19 12:54
true
阅读(2767)
评论(12)
编辑
收藏
引用
所属分类:
linux
Feedback
#
re: 自己造的一个线程类
2009-01-19 14:13
eXile
Win32最好不要使用CreateThread, 使用 _beginthreadex
回复
更多评论
#
re: 自己造的一个线程类[未登录]
2009-01-19 20:58
true
@eXile
嗯,这个网上有这种说法,不过我目前主要在linux,至于win下没那么讲究。
回复
更多评论
#
re: 自己造的一个线程类
2009-01-21 12:38
星绽紫辉
具体可查看《Windows核心编程》,里面讲到CreateThread可能不会释放tid线程块,而C运行库的_beginthreadex在内部调用了CreateThread,很好地解决了释放问题。
回复
更多评论
#
re: 自己造的一个线程类
2009-02-18 18:15
陈头
linux下使用,竟然不能使用工厂模式,
创建线程工厂有错误。原因是Run方法,郁闷
回复
更多评论
#
re: 自己造的一个线程类
2009-02-18 18:22
true
陈:
Run是纯虚函数,必须重载,然后才能实例化。
回复
更多评论
#
re: 自己造的一个线程类
2009-03-10 15:13
陈头
请问如何显示的析构 new 出来的线程类呢?
回复
更多评论
#
re: 自己造的一个线程类
2009-03-10 15:28
true
举个例子:
class CThreadTest : public CThread
{
protected:
void Run(void* arg)
{
printf("arg = %s\n",(char*)arg);
sleep(10);
printf("after sleep 10s");
}
};
步骤:
1.char* pArg = "hello";CThreadTest *pTest = new CThreadTest
2.pTest->Start(pArg);
3.pTest->Wait();
4.delete pTest;
你可以在CThreadTest 里面实现,delete的时候,自动终止线程
回复
更多评论
#
re: 自己造的一个线程类
2009-03-14 23:21
zengfanmaio
pthread_create第二个参数是空,默认有PTHREAD_CREATE_JOINABLE属性。因此,析构的时候,也要调用一下pthread_join(对应Win32的CloseHandle)。如果设置了PTHREAD_CREATE_DETACHED就不需要。:)
回复
更多评论
#
re: 自己造的一个线程类
2009-03-16 08:34
true
@zengfanmaio
好久不见!!
回复
更多评论
#
re: 自己造的一个线程类
2009-03-24 19:20
老陈头
谢谢
回复
更多评论
#
re: 自己造的一个线程类[未登录]
2009-09-11 20:16
欲三更
谢谢分享,很通用的设计,VCL类库里的TThread类基本就是这个样子。
说一点个人的想法:我自己写的类也差不多是这样,不过有一点差别:我个人认为“线程”和“线程要跑的任务”是两个东西,前者是内核对象(抱歉,我总是改不了用win32本位思考)的抽象,跟具体功能没关系,后者是功能的抽象,跟具体程序有关系。
所以我倾向于把static THREAD_API Routine(void* arg)分离出来,成为一个ITask接口。
这样做还有一个好处,当Thread跑完了Task的代码后可以阻塞在那里等待跑别的Task。
另外我对protobuf也蛮感兴趣的,但是我有点看不懂那个东西,功力太浅:)
回复
更多评论
#
re: 自己造的一个线程类
2009-09-11 20:34
true
@ 欲三更
线程的抽象问题,也算是见仁见智,你描述的方式类似boost的实现(好像是),而博文中的抽象是基于“主动对象”这个概念的,我个人觉得,“主动对象”更容易理解。
libprotobuf是个好东东,多看几遍就好了:),有啥问题可以一起交流。关于数据格式,还可以看一下json,感觉不错。
回复
更多评论
刷新评论列表
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
相关文章:
linux常用命令搜集
给ZThread提供一个patch
tcpdump的常用方式
C++实现的MD5算法
OCCI在linux上的编译警告
修改内核的部分参数
基础库的错误信息应该如何处理
对基本类型的再包装,方便了移植
自己造的一个线程类
linux下信号处理函数实现的一点理解
网站导航:
博客园
IT新闻
BlogJava
知识库
博问
管理
Powered by:
C++博客
Copyright © true