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;
}




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