线程!线程!线程!!!

1cctv 2011-02-13 04:41:53
加精
看到有的同学对bcb的线程认识不够深,特开一贴给同学们讲讲

主要给出两种常用的线程形式

1、长等待型线程示例,等待命令,执行不定长的工作,但每个工作的时间不会太长。
2、长工作型线程示例,执行一个很长时间的工作,但可以很快响应取消操作。

主程序

//---------------------------------------------------------------------------
#include "myThreadBUnit.h"
myThreadB *thb=NULL;
//---------------------------------------------------------------------------
void __fastcall TForm1::OnThreadMessage(TMessage& Message)
{
//与线程约定了,显示字串并delete它.
char *p=(char*)Message.LParam;
Memo1->Lines->Add(p);
delete p;

//BEGIN_MESSAGE_MAP
// MESSAGE_HANDLER(WM_USER+100,TMessage,OnThreadMessage);
//END_MESSAGE_MAP(TForm)
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//建立线程.
if(thb==NULL)
{
thb=new myThreadB(false);//创建线程并挂起,挂起的目的是向thb写参数.
thb->self=&thb;
thb->mainWin=Handle;
thb->msgMsg=WM_USER+100;
thb->Resume(); //运行线程.
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
//给线程一个命令.
if(thb!=NULL)
PostThreadMessage(thb->ThreadID,WM_USER+1000,1000,0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
//结束线程.
if(thb!=NULL)
{
if(!thb->exit())
ShowMessage("线程退出超时!");
}
}
//---------------------------------------------------------------------------

线程,myThreadBUnit.h

//---------------------------------------------------------------------------
#ifndef myThreadBUnitH
#define myThreadBUnitH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class myThreadB : public TThread
{
private:
void __fastcall runInit();
void __fastcall ShowMess(char *message);

protected:
void __fastcall Execute();
public:
__fastcall myThreadB(bool CreateSuspended);
__fastcall ~myThreadB(void); //析构函数.
HANDLE mainWin; //主线程窗体.
unsigned short int msgMsg; //与主线程通讯用,用于显示线程的消息.
myThreadB **self; //可以把主线程中的线程指针置NULL.
bool __fastcall exit(); //主线程调用,结束线程.
};
//---------------------------------------------------------------------------
#endif

线程,myThreadBUnit.cpp

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "myThreadBUnit.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------

// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall myThreadB::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall myThreadB::myThreadB(bool CreateSuspended)
: TThread(CreateSuspended)
{
//这里的代码运行在父线程的上下文中.

//无需显示使用delete,就可激活 析构函数.
FreeOnTerminate=true;
self=NULL;
mainWin=NULL;
msgMsg=0;
}
//---------------------------------------------------------------------------
__fastcall myThreadB::~myThreadB(void)
{
char mess[32];
wsprintf(mess,"thread:%d 退出",ThreadID);
ShowMess(mess);
if(self!=NULL)
*self=NULL;
}
//---------------------------------------------------------------------------
void __fastcall myThreadB::runInit()
{
//运行在当前线程环境中.
char mess[32];
wsprintf(mess,"thread:%d 建立",ThreadID);
ShowMess(mess);
}
//---------------------------------------------------------------------------
void __fastcall myThreadB::Execute()
{
MSG msg;
int i=0;
runInit();

//第一种工作形式是长等待,只是偶尔有工作需要做,很快做完又处于等待状态.
//比如标准的视频处理,每帧图像5ms处理完了,需要等35ms,下一帧图像才会来.

ShowMess("长等待");
while(true)//长等待型线程示例,等待命令,执行不定长的工作,但时间不会太长.
{
//检查消息队列,消息队列中无消息则阻塞在此,因此我叫它长等待.
GetMessage(&msg,NULL,0,-1);
if(msg.message==WM_USER+1000) //其它线程发来命令了.
{
Beep(1000,100);//模拟工作100毫秒.

//和主线程通一下讯.
char mess[32];
wsprintf(mess,"thread:%d i:%d",ThreadID,i++);
ShowMess(mess);
}
else if(msg.message==0) //其它线程发来退出消息.
{
if(msg.lParam!=0)
SetEvent((void*)msg.lParam);
break;
}
}

//第二种工作形式,线程是长工作状态.
//长工作又可分为两种形式,
//一种是处于某个冗长的循环中,
//一种是阻塞于某个事件或信号量中.

ShowMess("长工作");
while(true)//长工作型线程示例,执行一个很长时间的工作,但可以很快响应取消操作.
{
//既便是处于长工作状态中,也要想办法至少每秒检查1次消息队列.
//如果线程处于等待某个事件中而没有机会检查消息队列,参考exit()中的注释.

//无论消息队列中有无消息,PeekMessage()都不阻塞线程.
if(PeekMessage(&msg,NULL,0,-1,PM_REMOVE))
{
if(msg.message==0) //主线程发来退出消息.
{
if(msg.lParam!=0)
SetEvent((void*)msg.lParam);
break; //退出线程.
}
}
Beep(1000,1000);//模拟长工作秒.
}
}
//---------------------------------------------------------------------------
bool __fastcall myThreadB::exit()
{
//运行于调用线程的上下文中.

HANDLE exitEvent;
bool exitOK=true;

exitEvent=CreateEvent(NULL,false,false,NULL);
PostThreadMessage(ThreadID,0,0,(long)exitEvent);
//如果线程阻塞于某个事件xxxEvent中,那么需要用SetEvent(xxxEvent)使线程解除阻塞,
//以便线程有机会检查到上面发出的退出消息0.

//如果线程没有快速的检查到退出消息,那么调用线程最多等待(被阻塞)2000ms.
if(WAIT_TIMEOUT==WaitForSingleObject(exitEvent,2000))
exitOK=false;

CloseHandle(exitEvent);

return exitOK;
}
//---------------------------------------------------------------------------
void __fastcall myThreadB::ShowMess(char *message)
{
if(mainWin==NULL)
return;

char *newStr=new char[128];
lstrcpyn(newStr,message,128);
PostMessage(mainWin,msgMsg,0,(long)newStr);
//不要在此delete newStr.
//和主线程约定,newStr在主线程中delete.
}
//---------------------------------------------------------------------------




...全文
17709 207 打赏 收藏 转发到动态 举报
写回复
用AI写文章
207 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanglinming 2013-05-22
  • 打赏
  • 举报
回复
最近刚好遇到关于线程的问题...感谢楼主!!!
繁华落尽空 2013-03-16
  • 打赏
  • 举报
回复
270已经说清楚了, 不能屏蔽如下: BEGIN_MESSAGE_MAP MESSAGE_HANDLER(WM_USER+100,TMessage,OnThreadMessage); END_MESSAGE_MAP(TForm) 屏蔽了就没有消息接收函数了,自然接收不到消息
繁华落尽空 2013-03-16
  • 打赏
  • 举报
回复
引用 269 楼 w190231958 的回复:
引用 268 楼 illidianLV 的回复: 我也是这个问题,请问要怎么解决呢引用 228 楼 的回复:PostMessage(mainWin,msgMsg,0,(long)newStr); [BCC32 Error] myThreadBUnit.cpp(134): E2034 Cannot convert 'void *' to 'HWND__ *' Full parser ……
进行一次强制转换,如下: PostMessage((HWND__ *)mainWin,msgMsg,0,(long)newStr);
hgr2004 2013-01-27
  • 打赏
  • 举报
回复
把这段代码里面注释掉的
void __fastcall TForm1::OnThreadMessage(TMessage& Message)
{
   //与线程约定了,显示字串并delete它.
   char *p=(char*)Message.LParam;
   Memo1->Lines->Add(p);
   delete p;
   //BEGIN_MESSAGE_MAP
   //   MESSAGE_HANDLER(WM_USER+100,TMessage,OnThreadMessage);
   //END_MESSAGE_MAP(TForm)
}
这部分代码
  BEGIN_MESSAGE_MAP
     MESSAGE_HANDLER(WM_USER+100,TMessage,OnThreadMessage);
   END_MESSAGE_MAP(TForm)
放到Form1的头文件里面进行声明。 把消息的响应定义到自己的处理函数里面去,这样主窗口就可以接收到消息了。 BEGIN_MESSAGE_MAP MESSAGE_HANDLER(Windows消息名,TMessage,消息处理函数名) MESSAGE_HANDLER(...) END_MESSAGE_MAP(TForm)
w190231958 2012-11-26
  • 打赏
  • 举报
回复
引用 268 楼 illidianLV 的回复:
我也是这个问题,请问要怎么解决呢引用 228 楼 的回复:PostMessage(mainWin,msgMsg,0,(long)newStr); [BCC32 Error] myThreadBUnit.cpp(134): E2034 Cannot convert 'void *' to 'HWND__ *' Full parser context my……
我把定义的地方改为 HWND mainWin; //主线程窗体. 就可以通过了。但是目前,主窗体接送不到消息啊。
illidianLV 2012-09-11
  • 打赏
  • 举报
回复
我也是这个问题,请问要怎么解决呢[Quote=引用 228 楼 的回复:]
PostMessage(mainWin,msgMsg,0,(long)newStr);

[BCC32 Error] myThreadBUnit.cpp(134): E2034 Cannot convert 'void *' to 'HWND__ *'
Full parser context
myThreadBUnit.cpp(128): parsing: void _fastca……
[/Quote]
illidianLV 2012-09-11
  • 打赏
  • 举报
回复
我也是这个问题,请问要怎么解决呢[Quote=引用 228 楼 的回复:]
PostMessage(mainWin,msgMsg,0,(long)newStr);

[BCC32 Error] myThreadBUnit.cpp(134): E2034 Cannot convert 'void *' to 'HWND__ *'
Full parser context
myThreadBUnit.cpp(128): parsing: void _fastca……
[/Quote]
Richardw 2012-09-09
  • 打赏
  • 举报
回复
偷偷地收藏了一下,呵呵
dami1023 2012-01-05
  • 打赏
  • 举报
回复
标记一下,有用
  • 打赏
  • 举报
回复
可以啊,不错哦!
  • 打赏
  • 举报
回复
写得好
myking1206 2011-10-11
  • 打赏
  • 举报
回复
保存下来学习
txxxxxxzzzzzz 2011-10-08
  • 打赏
  • 举报
回复
连老妖都顶,那应该没错误。简单的多线程小程序我也会写,但是还是有必要多看看别人的例子,既然这么多人顶,我也看看楼主写的,与我写的有哪些不同,也许能学到点新东西,哈哈
stbigcrab 2011-10-08
  • 打赏
  • 举报
回复
做个标记,方便学习。
  • 打赏
  • 举报
回复
我只会C# 看不懂 攒分
小懒懒 2011-07-11
  • 打赏
  • 举报
回复
接分了
fbmsyu 2011-06-22
  • 打赏
  • 举报
回复
接分!!!!!
zhanghelpsgz 2011-06-21
  • 打赏
  • 举报
回复
好老的又翻出来了
wuweiwei20102010 2011-06-20
  • 打赏
  • 举报
回复
请问下怎么在Microsoft Visual C++ 6.0运行啊?
开始领悟 2011-06-20
  • 打赏
  • 举报
回复
学习了,呵呵
加载更多回复(187)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧