CSDN博客

img MantisXu

基于MFC的编写线程快速入门

发表于2002/12/30 9:15:00  632人阅读

分类: VC++开发

对于新手,编写线程,不知从何下手,不知编写线程要做那些,下面给出一个线程的简要框架

//////////////////////////////////////////////////////////////

//定义线程类YourThread.h
#if !defined(YOURTHREAD_INCLUDE_FILE)
#define YOURTHREAD_INCLUDE_FILE

  class CYourThread :public CWinThread
{
 ....
 DECLARE_DYNCREATE(CYourThread)
public:
 CYourThread();           // protected constructor used by dynamic creation

// Attributes
public:
  int m_bCloseFlag;
  HANDLE m_hEventKill;
  HANDLE m_hEventDead;
//操件
public:
      void KillThread();  //清除本线程

protected:
 virtual void SingleStep();
 virtual void Delete();
// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CEgClientCacheThread)
 public:
 virtual BOOL InitInstance();
 virtual int ExitInstance();
 virtual int Run();
 //}}AFX_VIRTUAL
// Implementation
public:
 virtual ~CYourThread();

 // Generated message map functions
 //{{AFX_MSG(CEgClientCacheThread)
  // NOTE - the ClassWizard will add and remove member functions here.
 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()
}
#ednif

////////////////////////////////////////////
//实现文件YourThread.cpp
#include "stdafx.h"
#include "YourThread.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CYourThread, CWinThread)
CYourThread::CYourThread()
{
 m_bAutoDelete = FALSE;  //注:该成员为CWinThread的成员,如为TRUE,在CWinThread::Delete()将删除线程
                         //置为FALSE不允许自动删除线程自已

 m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL);
 m_hEventDead = CreateEvent(NULL, TRUE, FALSE, NULL);
}

CYourThread::~CYourThread()
{

 CloseHandle(m_hEventKill);
 CloseHandle(m_hEventDead);
}
BOOL cYourThread::InitInstance()
{
 // TODO:  perform and per-thread initialization here
 // avoid entering standard message loop by returning FALSE
 return TRUE;  //用户接口线程,必须返回TRUE
   
     //如是 工作线程,代码如下
     /*
     while (WaitForSingleObject(m_hEventKill, 0) == WAIT_TIMEOUT)
       SingleStep();
 // 避免进入标准消息循环,必须返回FALSE
     return FALSE;
     */
}

CYourThread:SingleStep()
{
  //你的线程必一次执行的任务,每一次你的线程得到控制权,都会执行这个函数。
}

//如是用户接口线程,必须重载下面的函数
int CYourThread:Run
{
  //注:正面的代码 除了加注中文解释的外,其他的与CWinThread::Run()是完全一致的
    // for tracking the idle time state
 ASSERT_VALID(this);

 // for tracking the idle time state
 BOOL bIdle = TRUE;
 LONG lIdleCount = 0;

 // acquire and dispatch messages until a WM_QUIT message is received.
 for (;;)
 {
  SingleStep(); //执行本线程的单步函数
        if(m_bCloseFlag ==TRUE) //指示线程关闭
  {
            return ExitInstance();
  }
  // phase2: pump messages while available
        //必须用下列方式进行消息循环,因为CAsyncSocket用了标准的Windows消息循环来处理数据发送和接收入
  while (::PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE))  //必须先用PeekMessage进行消息检查
  {
   if(!(::GetMessage(&m_msgCur, NULL, NULL, NULL)))  //取消息
    return ExitInstance();

   if (!PreTranslateMessage(&m_msgCur))
   {
       ::TranslateMessage(&m_msgCur);
          ::DispatchMessage(&m_msgCur);
   }

            if (IsIdleMessage(&m_msgCur))
   {
    bIdle = TRUE;
    lIdleCount = 0;
   }

  }
 
 } 
 return ExitInstance();

}

int CYourThread::ExitInstance()
{
    //如是用户接口线程,此处完成你的清除任务

 VERIFY(SetEvent(m_hEventDead)); //这一句只有用户接口线程需要

 return CWinThread::ExitInstance();

  }

void CYourThread::Delete()
{
 // calling the base here won't do anything but it is a good habit?????????????

 //在CWinThread::Delete()如m_hAutoDelete为TRUE,则会删掉本进程
 CWinThread::Delete();

 // acknowledge receipt of kill notification
 VERIFY(SetEvent(m_hEventDead));
}

void CYourThread::KillThread()
{
 // Note: this function is called in the context of other threads,
 //  not the thread itself.

 // reset the m_hEventKill which signals the thread to shutdown
 VERIFY(SetEvent(m_hEventKill));

 // allow thread to run at higher priority during kill process
 SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
 WaitForSingleObject(m_hEventDead, INFINITE);

        //下面两行只有工作线程才能要
        /*
 WaitForSingleObject(m_hThread, INFINITE);
 delete this;
         */
}
////////////////////////////////////////////////
//启动线程
void startYourThread()
{
 CEgYourThread *pThread;
   if(!(pThread = (CYourThread*)AfxBeginThread(RUNTIME_CLASS(CYourThread),
      THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED)))
   {
  AfxMessageBox(_T("创建线程失败"));
  return ;
   }

VERIFY(pThread->SetThreadPriority(THREAD_PRIORITY_IDLE));  //设置优先级
  
 pEgThread->ResumeThread();  //启动线程
  }

///////////////////////////////////////////////////////
//下面是解释
注意:
 1   线程分两类: 工作线程 和 用户接口线程

  2  用户接口线程可以进行有如键盘输入的用户交互,而工作线程则没有。当然正在消息处理机制上也有差异。
  3 在线程初始化也不同. 如上面的例子
  4 在重复使用的线程上,工作线程与用户接口线程的清除也不一样.

 5 多线程时,必须解决资源冲突问题,刚开始学写线程时,可以用临界法来解决这个问题

在外部定义一个全局变量

    CRITICAL_SECTION  m_csYourThreadLock;  //线程同步锁

  在调用时初始化:

   InitializeCriticalSection(&m_csYourThreadLock)

 在退出所有线程后

 DeleteCriticalSection(&m_csYourThreadLock)

 

在SingleStep()函数中,对共享资源的处理,加上这一临界锁

void CYourThread::SingleStep()

{

EnterCriticalSection(&m_csYourThreadLock);

// 共享资源处理代码

LeaveCriticalSection(&m_csYourThreadLock);

//其他代码

}

 

0 0

相关博文

我的热门文章

img
取 消
img