Win32学习(第十一天)进程与线程初探

进程 通常被定义为一个正在运行的程序实例。
线程 线程是进程的一部分,线程总是在某个进程的环境中被创建,它是进程的某一个执行序列(像函数)。
在这里可以做一个比喻,如果把进程比喻成我们过去的地主的话,那么线程就相当于那个时代的长工。因为地主是非常懒的所以进程的活动性不强,如果想要通过一个进程完成某个操作,它必须有一个在它环境中运行的线程。如果需要完成多步操作,尽量通过多线程进行完成,这样可以尽可能节省足够多的资源。
进程的组成:操作系统用来管理进程的内核对象,地址空间(所有的可执行模块,像dll模块,所有需要的数据)
线程的组成:操作系统对线程管理实施的内核对象:线程堆栈。
要讲线程和进程还要先引入一个量程的概念,量程是操作系统为每一个线程安排了一定的CPU时间,它通过一种循环的方式为线程提供时间片。
下面是在Win32的窗口函数中创建一个进程的代码:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
		//创建一个进程
	case WM_LBUTTONDOWN:
	{STARTUPINFOW si;//新进程窗口的特性
		ZeroMemory(&si, sizeof(si));
		si.cb = sizeof(si);
		PROCESS_INFORMATION pi;//保存新进程的识别信息
		//进程的创建

		CreateProcess(_T("C:/Users/lzw/AppData/Local/Google/Chrome/Application/chrome.exe"),//可以执行的进程(路径名文件)
			nullptr,//命令行参数
			nullptr,//是否被子进程所继承
			nullptr,//是否被子线程所继承
			false,//新创建的进程是否从调用线程处继承了句柄
			0,//创建标志
			nullptr,//新进程的环境块
			nullptr,//子进程的工作路径
			&si,
			&pi);
		g_hInst = (HINSTANCE)pi.hProcess;
	}
		break;
//进程的结束方法:
		//1、主线程的入口函数返回(建议最好使用这种)
		//2、在父进程的某个线程出调用TerminateProcess去结束一个子进程
		//3、在当前进程的某个位置调用ExitProcess去结束这个子进程
	case WM_RBUTTONDOWN:
		TerminateProcess(g_hInst, 0);
		
		break;

	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择: 
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

下面再说线程:
线程是由两部分组成
1、操作系统内核 用来存放线程的统计信息。
2、线程堆栈 用来维护线程代码过程中所需要的 的所有函数的参数和局部变量。

线程总是在进程中被创建的,线程的生命周期会受到进程的影响:
1、进程一旦被创建,系统必然会同时给出一个主线程
2、进程一旦死亡,这个进程里面的所有线程都会死亡
3、线程需要的资源比进程要少,进程有不活跃,如果需要异步解决问题因尽量创建线程,避免创建进程。
下面是一段使用对话框创建的线程代码:
#include<stdio.h>
#include<windows.h>
int myadd(int a, int b)
{ return a + b; }
int piao = 10;//票数
void aaa(LPVOID v)
{
myadd(1, 2);
while (true)
{
if (piao > 0)
{
printf(“第%d个代售点卖出%d张票\n”, (int)v, piao);
piao–;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int index = 1;
HANDLE handle1 = CreateThread(nullptr,//指向SECURITY_ATTRIBUTES结构的指针
0,//线程堆栈的大小,默认给0
(LPTHREAD_START_ROUTINE)aaa,//调用的哪一个函数,把这个函数做为线程执行函数
(LPVOID)index,//传递给线程函数的参数
0,//线程创建的参数
nullptr);//新线程的id
index++;
HANDLE handle2 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)aaa, (LPVOID)index, 0, nullptr);
index++;
HANDLE handle3 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)aaa, (LPVOID)index, 0, nullptr);
index++;
HANDLE handle4 = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)aaa, (LPVOID)index, 0, nullptr);
while (true)
{
if (piao > 0)
{
printf(“火车站卖出第%d张票\n”, piao);
piao–;
}
else
break;
}
//线程的三种退出:
//1、线程函数的主动返回(建议)
//2、在某个线程里面去调用TerminateThread结束某个指定的子线程
//3、在某个线程里面调用ExitThread结束当前线程
TerminateThread(handle1, 0);
TerminateThread(handle2, 0);
TerminateThread(handle3, 0);
TerminateThread(handle4, 0);
getchar();
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41848597/article/details/89245649