首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

线程!线程!线程!该怎么解决

2013-01-04 
线程!线程!线程!!!,特开一贴给同学们讲讲。主要给出两种常用的线程形式。1、长等待型线程示例,等待命令,执行

线程!线程!线程!!!
,特开一贴给同学们讲讲线程!线程!线程!该怎么解决

主要给出两种常用的线程形式线程!线程!线程!该怎么解决

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.
}
//---------------------------------------



线程!线程!线程!该怎么解决


[解决办法]
接分来了。
[解决办法]
线程!线程!线程!该怎么解决

热点排行