创建线程的函数使用

线程创建有几个主要的函数,CreateThreadAfxBeginThread

其中,在MFC环境下一般体检使用AfxBeginThread这个函数,原因是因为CreateThread这个函数使用并不安全。在MFC中使用AfxBrginThread偏多。

在使用AfxBeginThread的过程中,有几个参数比较重要,而且AfxBeginThread有两种使用格式,在MSDN中的格式如下:

CWinThread* AfxBeginThread(

   AFX_THREADPROC pfnThreadProc,

   LPVOID pParam,

   int nPriority = THREAD_PRIORITY_NORMAL,

   UINT nStackSize = 0,

   DWORD dwCreateFlags = 0,

   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL

);

CWinThread* AfxBeginThread(

   CRuntimeClass* pThreadClass,

   int nPriority = THREAD_PRIORITY_NORMAL,

   UINT nStackSize = 0,

   DWORD dwCreateFlags = 0,

   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL

);

如果使用的是第一个格式的函数的话,第一个参数和第二个参数很重要。其中第一个参数就是你的线程要启动的函数,就是线程的入口函数,这个函数有固定的格式,格式错误就不能够调用成功。而第二个函数这是该函数的参数。入口函数的格式如下:

UINT __cdeclMyControllingFunction( LPVOID pParam );

但是有一个问题,由于线程入口函数要求是全局函数,因此当我想要以线程方式启动我某个类的成员函数的时候,我该怎么做呢??

有两种方法,一种是将我的成员函数设置成静态函数,以供调用,但是静态函数是不能够调用类中的非静态成员函数,这就是吃力不讨好了。

第二种就是在外面创建一个全局函数,在全局函数中将入口函数的指针强制转换成类指针,然后通过指针调用成员函数,这个可以使用。

 

UINT  CalSDInfo( LPVOID pParam )

{

   CStoreViewDlg   *pStoreView = (CStoreViewDlg*)pParam ;

       pStoreView->GetSDUseInfo();

       return 0;

}

通过这种格式的调用就能够调用类的成员函数了。

关于线程结束的方式也有两种,一种是我上面的使用方式,在入口函数执行完之后return 0,线程执行完入口函数之后,自然结束线程。但是这个方式也有缺点,比如说在入口函数还未执行完的时候,我离开了当前菜单,之后重新进入该菜单,这个时候程序又要重新创建一个线程再次计算这个结果,而且上个入口函数还没有执行完,这就会导致数据错误了!当然,如果通过一个循环来控制的话,就可以解决了,但是稍微要麻烦一点了,所以就采用下面的方法了!

为了辅助这种设计,因此,还需要强制停止线程。强制停止线程可以通过函数TerminateThread来完成。具体的调用格式如下:

      DWORD threadActive;

      GetExitCodeThread(m_thread->m_hThread,&threadActive);

      if (STILL_ACTIVE  ==threadActive)

      {

            TerminateThread(m_thread->m_hThread,0);

      }

先对线程进行判断,判断线程是否还在运行,如果线程仍然运行的话,则强行终止线程。不过这个函数也有一定的缺陷,问题就是可能会造成死锁。这个问题先留住,下次就针对这几个线程结束的函数进行比对!

你可能感兴趣的:(创建线程的函数使用)