线程安全退出

#include <windows.h> #include <iostream>
using namespace std;

DWORD WINAPI ThreadProc(LPVOID);

LPCTSTR EVENT_NAME = _T("TEST");

int _tmain(int argc, _TCHAR* argv[])
{
    
    HANDLE hThread = NULL;
    HANDLE hEvent = NULL;

    hEvent = CreateEvent(NULL, TRUE, FALSE, EVENT_NAME);
    hThread = CreateThread(NULL,NULL,ThreadProc,NULL,0,NULL);
    ::Sleep(1000);
    
    ::SetEvent(hEvent);
    ::WaitForSingleObject(hThread, INFINITE);
    ::CloseHandle(hThread);
    ::CloseHandle(hEvent);

    cout << "Main exits " << endl;
    return 0;
}


DWORD WINAPI ThreadProc(LPVOID)
{
    HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME);
    ::WaitForSingleObject(hEvent, INFINITE);
    ::CloseHandle(hEvent);
    cout << "Thread exits" << endl;
    return 0L;
}


#include <windows.h>
#include <iostream>
using namespace std;

DWORD WINAPI ThreadProc(LPVOID);

LPCTSTR EVENT_NAME = _T("TEST");
DWORD    THREAD_CYCLE = 500;

int MainFirst();
int MainSecond();

int _tmain(int argc, _TCHAR* argv[])
{
    MainFirst();
    //MainSeond();
    
}

int MainFirst()
{
    HANDLE hThread = NULL;
    HANDLE hEvent = NULL;

    hEvent = CreateEvent(NULL, TRUE, FALSE, EVENT_NAME);
    hThread = CreateThread(NULL,NULL,ThreadProc,NULL,0,NULL);
    ::Sleep(3000);
    
    ::SetEvent(hEvent);
    ::WaitForSingleObject(hThread, INFINITE);
    ::CloseHandle(hThread);
    ::CloseHandle(hEvent);

    cout << "Main exits " << endl;
    return 0;
}

int MainSecond()
{
    HANDLE hThread = NULL;
    HANDLE hEvent = NULL;

    hEvent = CreateEvent(NULL, TRUE, FALSE, EVENT_NAME);
    hThread = CreateThread(NULL,NULL,ThreadProc,NULL,0,NULL);
    ::Sleep(3000);
    
    ::SetEvent(hEvent);
    // no blocking
    //::WaitForSingleObject(hThread, INFINITE); 
    ::CloseHandle(hThread);
    ::CloseHandle(hEvent);

    cout << "Main exits " << endl;
    return 0;
}

DWORD WINAPI ThreadProc(LPVOID)
{
    HANDLE hEvent = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, EVENT_NAME);
    while (WAIT_TIMEOUT == ::WaitForSingleObject(hEvent, THREAD_CYCLE))
    {
        cout << "Thread is running" << endl;
    }
    ::CloseHandle(hEvent);
    cout << "Thread exits" << endl;
    return 0L;
}

(1)线程函数返回(最好使用这种方法)
  这是确保所有线程资源被正确地清除的唯一办法。如果线程能够返回,就可以确保下列事项的实现:在线程函数中创建的所有C++对象均将通过它们的撤消函数正确地撤消。操作系统将正确地释放线程堆栈使用的内存。系统将线程的退出代码设置为线程函数的返回值。系统将递减线程内核对象的使用计数。
(2)调用ExitThread函数(最好不要使用这种方法)
  该函数将终止线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但是,C++资源(如C++类对象)将不被撤消。
(3)调用TerminateThread函数(应该避免使用这种方法)
  TerminateThread能撤消任何线程。线程的内核对象的使用计数也被递减。TerminateThread函数是异步运行的函数。如果要确切地知道该线程已经终止运行,必须调用WaitForSingleObject或者类似的函数。当使用返回或调用ExitThread的方法撤消线程时,该线程的内存堆栈也被撤消。但是,如果使用TerminateThread,那么在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈。
(4)包含线程的进程终止运行(应该避免使用这种方法)
  由于整个进程已经被关闭,进程使用的所有资源肯定已被清除。就像从每个剩余的线程调用TerminateThread一样。这意味着正确的应用程序清除没有发生,即C++对象撤消函数没有被调用,数据没有转至磁盘等等。一旦线程不再运行,系统中就没有别的线程能够处理该线程的句柄。然而别的线程可以调GetExitcodeThread来检查由hThread标识的线程是否已经终止运行。如果它已经终止运行,则确定它的退出代码。
安全的结束一个线程的最好的方法就是让线程自己返回。
一个比较好的方法如下:
1、在主线程中创建一个Event。
2、在线程中等待这个Event,如果主线程希望线程终止,释放所有的资源,返回。

代码示意:
HANDLE hExitEvent = NULL; // 退出Event

DWORD WINAPI THreadFunc(LPVOID pPrama)
{
.....
if(WaitForSingleObject(hExitEvent, 0) != WAIT_TIMEOUT)
{
.......//退出前释放所有创建的资源
return 0;
}

}


int main()
{
.......
hExitEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//这里可以设置为手动Event也可以设置成自动Event,看需求而定。
CreateThread(....,THreadFunc, NULL);
.......
.......
SetEvent(hExitEvent );//希望线程退出
}

安全的结束一个线程的最好的方法就是让线程自己返回。 
一个比较好的方法如下: 
1、在主线程中创建一个Event。 
2、在线程中等待这个Event,如果主线程希望线程终止,释放所有的资源,返回。 

代码示意: 
HANDLE hExitEvent = NULL; // 退出Event 

DWORD WINAPI THreadFunc(LPVOID pPrama) 
{ 
..... 
if(WaitForSingleObject(hExitEvent, 0) != WAIT_TIMEOUT) 
{ 
.......//退出前释放所有…


补充一下:

if(WaitForSingleObject(hExitEvent, 0) != WAIT_TIMEOUT) //这里一旦发现超时,就是有人希望立刻终止这个线程。
{ 
.......//退出前释放所有创建的资源 
return 0; 
} 
一个线程程的结束:waitforsingleobject
多个线程的结束(包括全部结束和随便一个结束):waitformultipleobjects
多个线程的结束(某几个确定的结束):比较复杂,参考windows核心编程第10章waitformultexp程序。

the end of one thread :invoke waitforsingleobject
the end of several threads(including the situation about the end of all the threads and the end of anyone among these threads): invoke waitformultipleobjects
the end of several threads(after the end of some threads among these threads): a little complicated, refer to the advanced programming of windows chapter 10, appended programme waitformulext

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值