windows结束线程的三种方式

windows 结束线程有三种方式

一、让线程函数执行到 return

二、在线程函数内调用 ExitThread

三、调用 TerminateThread

其中前两种方式比较类似,它们都是通过修改某个变量来达到改变子线程执行流程,从而实现退出的目的。这两种方式是同步的,安全的,线程退出后会系统会清理堆栈。

第三种方式 TerminateThread 是异步的,它会创建一个新的线程去结束我们希望干掉的线程,该函数立即返回,是异步的。如果程序希望线程真的结束,然后再往下走,那么就需要在 TerminateThread 后面调用 WaitForSingleObject 函数,阻塞等待线程真的结束。

如果希望子线程安全地退出,并执行释放资源代码,使用方式一;
如果希望子线程直接退出,没有需要释放的资源,可以使用方式二;
第三种方式结束线程不安全,系统不会清理子线程的堆栈,不推荐使用。

这是我写的一个测试程序:
在这里插入图片描述

下面附上三种结束方式的实现

方式一(推荐)

// ThreadOperatorGUI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

BOOL flag = TRUE; // 控制子线程结束

DWORD WINAPI MyThread(LPVOID lpParam)
{
	HWND hEdit = (HWND)lpParam;
	TCHAR szBuffer[10];
	GetWindowText(hEdit, szBuffer, 10);	
	for (int i = 0; i <= 10000; i++)
	{
		if (!flag) break;
		_stprintf(szBuffer, TEXT("%d"), i);
		SetWindowText(hEdit, szBuffer);		
		Sleep(200);
	}
	return 0;
}

BOOL CALLBACK MainDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hEdit;
	static HANDLE hThread;

	switch(uMsg)
	{
	case WM_CLOSE:
		{
			EndDialog(hDlg, 0);
			return TRUE;
		}
	case WM_INITDIALOG:
		{
			hEdit = GetDlgItem(hDlg, IDC_EDIT);
			SetWindowText(hEdit, "0");
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					hThread = CreateThread(0, 0, MyThread, hEdit, 0, 0);
					return TRUE;
				}
			case IDC_BUTTON2:
				{
					SuspendThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON3:
				{
					ResumeThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON4:
				{
					flag = FALSE;
					return TRUE;
				}
			}
		}
	}
	return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDialogProc);

	return 0;
}




方式二

// ThreadOperatorGUI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

BOOL flag = TRUE; // 控制子线程结束

DWORD WINAPI MyThread(LPVOID lpParam)
{
	HWND hEdit = (HWND)lpParam;
	TCHAR szBuffer[10];
	GetWindowText(hEdit, szBuffer, 10);	
	for (int i = 0; i <= 10000; i++)
	{
		if (!flag) ExitThread(1);
		_stprintf(szBuffer, TEXT("%d"), i);
		SetWindowText(hEdit, szBuffer);		
		Sleep(200);
	}
	return 0;
}

BOOL CALLBACK MainDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hEdit;
	static HANDLE hThread;

	switch(uMsg)
	{
	case WM_CLOSE:
		{
			EndDialog(hDlg, 0);
			return TRUE;
		}
	case WM_INITDIALOG:
		{
			hEdit = GetDlgItem(hDlg, IDC_EDIT);
			SetWindowText(hEdit, "0");
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					hThread = CreateThread(0, 0, MyThread, hEdit, 0, 0);
					return TRUE;
				}
			case IDC_BUTTON2:
				{
					SuspendThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON3:
				{
					ResumeThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON4:
				{
					flag = FALSE;
					return TRUE;
				}
			}
		}
	}
	return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDialogProc);

	return 0;
}




方式三(不推荐)

// ThreadOperatorGUI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

DWORD WINAPI MyThread(LPVOID lpParam)
{
	HWND hEdit = (HWND)lpParam;
	TCHAR szBuffer[10];
	GetWindowText(hEdit, szBuffer, 10);	
	for (int i = 0; i <= 10000; i++)
	{
		_stprintf(szBuffer, TEXT("%d"), i);
		SetWindowText(hEdit, szBuffer);		
		Sleep(200);
	}
	return 0;
}

BOOL CALLBACK MainDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hEdit;
	static HANDLE hThread;

	switch(uMsg)
	{
	case WM_CLOSE:
		{
			EndDialog(hDlg, 0);
			return TRUE;
		}
	case WM_INITDIALOG:
		{
			hEdit = GetDlgItem(hDlg, IDC_EDIT);
			SetWindowText(hEdit, "0");
			return TRUE;
		}
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					hThread = CreateThread(0, 0, MyThread, hEdit, 0, 0);
					return TRUE;
				}
			case IDC_BUTTON2:
				{
					SuspendThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON3:
				{
					ResumeThread(hThread);
					return TRUE;
				}
			case IDC_BUTTON4:
				{
					TerminateThread(hThread, 123); // 结束码123,可自定义
					WaitForSingleObject(hThread, INFINITE); // 阻塞,直到hThread结束
					return TRUE;
				}
			}
		}
	}
	return FALSE;
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), 0, MainDialogProc);

	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章