MFC 多线程(转)

MFC 多线程(转)  

 

MFC中线程的创建

 

1. 线程的创建

Example 1:工作者线程

UINT MyThreadProc( LPVOID pParam )

{

    CMyObject* pObject = (CMyObject*)pParam;

 

    if (pObject == NULL ||

        !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))

    return 1;   // if pObject is not valid

 

    // do something with 'pObject'

 

    return 0;   // thread completed successfully

}

 

// inside a different function in the program

 

pNewObject = new CMyObject;

AfxBeginThread(MyThreadProc, pNewObject);

 

Example 2:工作者线程

UINT MyThreadProc(LPVOID pParam)

{

        for (UINT i=0;i<reinterpret_cast<UINT>(pParam);i++)

        {

                if (i==50)

                        AfxEndThread(0, TRUE);  //end thread with exit code 0

                ::Sleep(100);

                TRACE(_T("%d\n"), i);

        }

        return 0L;

}

 

// inside a different function in the program

        pThread = AfxBeginThread(MyThreadProc, reinterpret_cast<LPVOID>(128), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

        …

        …

        …

        pThread->ResumeThread();        //start the thread

 

 

Example 3: 用户界面线程

//

// Header File

//

class CUIThread:public CWinThread

{

        DECLARE_DYNCREATE(CUIThread);

public:

        virtual BOOL InitInstance();

        virtual int ExitInstance();

};

 

class CMainWindow : public CFrameWnd    //define a CFrameWnd class

{

public:

        CMainWindow()   {Create(NULL, _T("User Interface Thread Window"));}

};

 

//

// CPP file

//

IMPLEMENT_DYNCREATE(CUIThread, CWinThread)

BOOL CUIThread::InitInstance()

{

        m_pMainWnd = new CMainWindow;

        m_pMainWnd->ShowWindow(SW_SHOW);

        m_pMainWnd->UpdateWindow();

        return TRUE;

}

int CUIThread::ExitInstance()

{

        m_pMainWnd->DestroyWindow();

        delete m_pMainWnd;

        m_pMainWnd = NULL;

        return CWinThread::ExitInstance();

}

 

 

// inside a different function in the program

 

void CWinThreadApp::StartUIthread()

{

        // TODO: Add your command handler code here

        pThread = AfxBeginThread(RUNTIME_CLASS(CUIThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

        //pThread->m_bAutoDelete = TRUE;

        pThread->ResumeThread();

}

 

void CWinThreadApp::ReleaseThread()

{

        DWORD dwExitCode;

        ::GetExitCodeThread(pThread->m_hThread, &dwExitCode);

        if (dwExitCode == STILL_ACTIVE)

        {

                pThread->PostThreadMessage(WM_QUIT, 0, 0);      //Post WM_QUIT message to terminate UI thread

        }

}

 

2. 线程的结束

ExitThread is the preferred method of exiting a thread in C code. However, in C++ code, the thread is exited before any destructors can be called or any other automatic cleanup can be performed. Therefore, in C++ code, you should return from your thread function.

When this function is called (either explicitly or by returning from a thread procedure), the current thread's stack is deallocated, all pending I/O initiated by the thread is cancelled, and the thread terminates. The entry-point function of all attached dynamic-link libraries (DLLs) is invoked with a value indicating that the thread is detaching from the DLL.

If the thread is the last thread in the process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the operating system. A thread object is deleted when the last handle to the thread is closed.

 

TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.

TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:

> If the target thread owns a critical section, the critical section will not be released.

> If the target thread is allocating memory from the heap, the heap lock will not be released.

If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.

If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

A thread cannot protect itself against TerminateThread, other than by controlling access to its handles. The thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.

If the target thread is the last thread of a process when this function is called, the thread's process is also terminated.

The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter.

Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.

 

AfxEndThread: Call this function to terminate the currently executing thread.

void AFXAPI AfxEndThread(

   UINT nExitCode,

   BOOL bDelete = TRUE

);

Parameters

nExitCode

Specifies the exit code of the thread.

bDelete

Deletes the thread object from memory.

 

3. 线程对象的销毁

CWinThread::m_bAutoDelete属性设置为FALSE后,必须手动删除Thread对象;否则Thread对象会被自动删除,相应的线程句柄CWinThread::m_hThread也被销毁。对于函数线程,函数体return后,工作者线程被销毁;对于UI线程,给其消息队列发送WM_QUIT后会销毁UI线程。

 

Example 4:线程的手动删除

        pThread = AfxBeginThread(RUNTIME_CLASS(CUIThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

        pThread->m_bAutoDelete = FALSE;

        pThread->ResumeThread();

 

// inside a different function in the program

        delete pThread;

 

Example 5:一个删除线程的错误例子

// Create thread

        pThread->m_bAutoDelete = TRUE;

// Call AfxEndThread during thread running

        AfxEndThread(0, TRUE);

// inside a different function in the program

        delete pThread

第三步delete pThread将是不必要的,不管是工作者线程自然结束还是使用AfxEndThread(第二个参数是TRUE,删除Thread对象),都使得thread对象已被删除,所以delete是不必要的。

4. 线程的查询

        DWORD dwProcessId = ::GetCurrentProcessId();    //获取当前进程ID

        DWORD dwThreadId = ::GetCurrentThreadId();      //获取当前线程ID

        DWORD dwThreadId = ::AfxGetThread()->m_nThreadID); //获取当前线程ID

        CWnd* pWndMain = ::AfxGetMainWnd();     //获取当前线程的FrameWnd对象

 

 

转自:http://elevenjohns.blog.163.com/blog/static/97981620081112112450327/

 

代码来自产学研的数据库实习,CUseLoginDlg类。


//
启动一个线程
void StartThread(CWinThread*& pThread, AFX_THREADPROC pfnThreadProc, LPVOIDpParam)

 // TODO: Add your command handler code here 
 //
类线程
// pThread = AfxBeginThread(RUNTIME_CLASS(<classname>),THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);  
// pThread->ResumeThread();//
启动线程 

 //函数API线程
    pThread = AfxBeginThread(pfnThreadProc,pParam, THREAD_PRIORITY_NORMAL, 0, 0);
}


//
结束一个线程
void ReleaseThread(CWinThread* pThread)

 DWORD dwExitCode; 
 ::GetExitCodeThread(pThread->m_hThread, &dwExitCode); 
 if (dwExitCode == STILL_ACTIVE)  
 {  
  pThread->PostThreadMessage(WM_QUIT, 0,0);      //Post WM_QUIT message to terminate UIthread  
 } 
}

//获取一个线程的信息(可以用于控制一个线程的结束)
DWORD Get_OtherThread_Info(CWinThread* pThread, DWORD waittime)
{
 return (WaitForSingleObject(pThread->m_hThread, waittime));
}

//数据库连接线程
UINT ConnectDBThread(LPVOID pParam)
 
 return (UINT)(CUserLoginDialog::Connect());
 
}

UINT IsSQLServerOpen(LPVOID pParam)
{
 long userNum;
 CUserOperate *pUser_op = (CUserOperate*)(pParam);
    return pUser_op->GetUserNum(userNum);
}

 

使用:

 long userNum;  
 DWORD waitime = 3000;//ms 
 CWinThread* pThread;
 //
如果服务管理器没有打开,对数据库的操作将失败
 
 StartThread(pThread, IsSQLServerOpen, (LPVOID)pUser_Oper);
// SetThreadPriority(pThread, THREAD_PRIORITY_BELOW_NORMAL);
/* info_dlg.ShowWindow(SW_HIDE);*/

 DWORD ThreadState = Get_OtherThread_Info(pThread,waitime);
    ReleaseThread(pThread);

//  CString st;
//  st.Format("%d", ThreadState);
//  MessageBox(st);
    if ( ThreadState != WAIT_OBJECT_0 )//
如果数据库处于激活状态(连接超时)
 {
  MessageBox("
侦测到您的数据库服务器没有打开,连接超时!", "ERROR", MB_OK | MB_ICONERROR);
  CCreateDB_Step1 Step1_Dlg;
  Step1_Dlg.DoModal();
  Step1_Dlg.ShowWindow(SW_SHOW);  
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值