windows核心编程之线程进程的基本使用

在这里插入图片描述

来源:微信公众号「编程学习基地」

Process进程

在windows系统中,进程就是一个正在运行的程序,他拥有自己的虚拟地址空间,拥有自己的代码,数据和其他系统资源,一个进程也包含了一个或多个运行在此进程中的线程

CreateProcess函数

BOOL CreateProcess 
( 
	LPCTSTR lpApplicationName, 	//可执行文件名称
	LPTSTR lpCommandLine, 		//指定了要传递给执行函数的参数
	LPSECURITY_ATTRIBUTES lpProcessAttributes,//NULL
	LPSECURITY_ATTRIBUTES lpThreadAttributes,  //NULL
	BOOL bInheritHandles, 		//指定是否可以被新进程继承
	DWORD dwCreationFlags, 		//进程优先级
	LPVOID lpEnvironment, 		//新进程使用的环境变量
	LPCTSTR lpCurrentDirectory, //新进程当前目录
	LPSTARTUPINFO lpStartupInfo, //主窗口的位置,大小和标准句柄
	LPPROCESS_INFORMATION lpProcessInformation //返回进程的标志信息
); 

进程STARTUPINFO

typedef struct _STARTUPINFO 
{
    
     
	DWORD cb;			//包含STARTUPINFO结构中的字节数,将cb初始化为sizeof(STARTUPINFO) 
    PSTR lpReserved;	//保留。必须初始化为NULL
    PSTR lpDesktop;		//指定桌面名称
    PSTR lpTitle;		//控制台应用程序标题
    DWORD dwX;			//用于设定应用程序窗口相对屏幕左上角位置的x 坐标(以像素为单位)。 
    DWORD dwY;		    //对于GUI processes用CW_USEDEFAULT作为CreateWindow的x、y参数
    DWORD dwXSize;		//用于设定应用程序窗口的宽度(以像素为单位)
    DWORD dwYSize;			 
    DWORD dwXCountChars;//控制台窗口的行数
    DWORD dwYCountChars; 
    DWORD dwFillAttribute;   //用于设定子应用程序的控制台窗口使用的文本和背景颜色 
    DWORD dwFlags;           //请参见下一段和表4-7 的说明 
    WORD wShowWindow;        //窗口的风格
    WORD cbReserved2;        //保留。必须被初始化为0 
    PBYTE lpReserved2;       //保留。必须被初始化为NULL
    HANDLE hStdInput;        //用于设定供控制台输入和输出用的缓存的句柄。
    HANDLE hStdOutput; 
    HANDLE hStdError; 
} STARTUPINFO, *LPSTARTUPINFO;

获取当前进程的STARTUPINFO结构:GetStartupInfo();

简单使用

#include<Windows.h>
#include<stdio.h>
int main()
{
    
    
	STARTUPINFO si = {
    
     sizeof(si) };
	PROCESS_INFORMATION pi;
	CreateProcess("C:\\Program Files\\Notepad++\\notepad++.exe",//需要创建的进程是谁(路径文件名)
		nullptr,//命令行参数
		nullptr,//是否被子进程所继承
		nullptr,//是否被子线程所继承
		false,//新创建的进程是否从调用线程处继承了句柄
		0,//创建标志
		nullptr,//新进程的环境块
		nullptr,//子进程的工作路径
		&si,
		&pi);
	printf("新的进程Id:%d\n", pi.dwProcessId);
	return 0;
}

程序运行会打开电脑C盘C:\\Program Files\\Notepad++\\notepad++.exe路径下的NotePad程序

#include<Windows.h>
int main()
{
    
    
	STARTUPINFO si = {
    
     sizeof(si) };
	PROCESS_INFORMATION pi;
	char* Command = "notepad";
	CreateProcess(NULL, Command, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
	return 0;
}

程序运行创建进程,打开记事本,这是通过参数打开的

结束进程的方法

  1. 该进程的主线程的入口函数返回(等同于你结束创建的进程)
  2. 在父进程的某个线程处调用TerminateProcess去结束一个子进程
  3. 在当前进程的某个位置调用ExitProcess去结束自己
#include<Windows.h>
#include<stdio.h>
int main()
{
    
    
	STARTUPINFO si = {
    
     sizeof(si) };
	PROCESS_INFORMATION pi;
	CreateProcess("C:\\Program Files\\Notepad++\\notepad++.exe",//需要创建的进程是谁(路径文件名)
		nullptr,//命令行参数
		nullptr,//是否被子进程所继承
		nullptr,//是否被子线程所继承
		false,//新创建的进程是否从调用线程处继承了句柄
		0,//创建标志
		nullptr,//新进程的环境块
		nullptr,//子进程的工作路径
		&si,
		&pi);
	printf("新的进程Id:%d\n", pi.dwProcessId);
	HANDLE hinst = pi.hProcess;	//获取该进程的示例句柄
	Sleep(3000);
	//终止当前进程
	//第一种方法就是手动关掉notepad
	TerminateProcess(hinst, NULL);	
	//ExitProcess(0);
	CloseHandle(hinst);
	return 0;
}

Thread线程

CreateThread函数

HANDLE WINAPI CreateThread(
	  _In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes,   
	  _In_      SIZE_T                 dwStackSize,
	  _In_      LPTHREAD_START_ROUTINE lpStartAddress,
	  _In_opt_  LPVOID                 lpParameter,
	  _In_      DWORD                  dwCreationFlags,
	  _Out_opt_ LPDWORD                lpThreadId
	);

参数说明:

  • 第一个参数 lpThreadAttributes 表示线程内核对象的安全属性,一般传入NULL表示使用默认设置。
  • 第二个参数 dwStackSize 表示线程栈空间大小。传入0表示使用默认大小(1MB)。
  • 第三个参数 lpStartAddress 表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址。
  • 第四个参数 lpParameter 是传给线程函数的参数。
  • 第五个参数 dwCreationFlags 指定额外的标志来控制线程的创建,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED则表示线程创建后暂停运行,这样它就无法调度,直到调用ResumeThread()。
  • 第六个参数 lpThreadId 将返回线程的ID号,传入NULL表示不需要返回该线程ID号。

返回值

线程创建成功返回新线程的句柄,失败返回NULL

WaitForSingleObject函数

DWORD WINAPI WaitForSingleObject(
    _In_ HANDLE hHandle,
    _In_ DWORD dwMilliseconds
    );

第一个参数 _In_ HANDLE hHandle 是对象的句柄,可以是以下几种:

第二个参数 _In_ DWORD dwMilliseconds 为等待时间,以毫秒为单位。

参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。

若为0,则该函数立即返回;

若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。

#include <stdio.h>
#include <windows.h>

// 线程函数
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    
    
	for (int i = 0; i < 10; i++)
	{
    
    
		printf("I am Thread :%d\trun\n", GetCurrentThreadId());
		
	}
	return 0;
}

int  main(int argc, char* argv[])
{
    
    
	HANDLE hThread;
	DWORD dwThreadId;

	// 创建一个线程
	hThread = CreateThread(
		NULL,		// 默认安全属性
		NULL,		// 默认堆栈大小
		ThreadProc,	// 线程入口地址(执行线程的函数)
		NULL,		// 传给函数的参数
		0,		// 指定线程立即运行
		&dwThreadId);	// 返回线程的ID号
	printf(" Now another thread has been created. ID = %d \n", dwThreadId);

	// 等待新线程运行结束
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44519484/article/details/108754540
今日推荐