目录
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,也是操作系统结构的基础。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
从理论角度看,进程是对正在运行的程序过程的抽象;从实现角度看,进程是一种数据结构,目的在于清晰地刻画动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。
进程具有动态性,它是动态产生和消亡的。每一个进程都有它自己的地址空间,包括文本区域、数据区域和堆栈。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
进程与程序有本质的区别。程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念,有一定的生命期。程序是永久的,进程是暂时的。进程更能真实地描述并发,而程序不能。此外,进程具有创建其他进程的功能,而程序没有。同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程,即同一程序可以对应多个进程。
1、创建进程
在C++中创建Windows进程通常涉及到使用Windows API函数,特别是CreateProcess函数。这个函数允许你启动一个新的进程和它的主线程,并指定新进程的命令行、初始窗口状态、环境块等。
以下是一个简单的示例,展示了如何使用CreateProcess函数来创建一个新的Windows进程:
#include <windows.h> #include <tchar.h> #include <iostream> int main() { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); // 设置命令行参数,这里以notepad.exe为例 TCHAR cmdLine[] = _T("C:\\Windows\\System32\\notepad.exe"); // 创建进程 if (!CreateProcess(NULL, // 不使用模块名 cmdLine, // 命令行 NULL, // 进程句柄不可继承 NULL, // 线程句柄不可继承 FALSE, // 设置句柄不继承标志 0, // 无创建标志 NULL, // 使用父进程的环境块 NULL, // 使用父进程的驱动器和目录 &si, // 指向STARTUPINFO结构的指针 &pi) // 指向PROCESS_INFORMATION结构的指针 ) { std::cerr << "CreateProcess failed (" << GetLastError() << ")." << std::endl; return 1; } // 等待进程结束,以便看到notepad窗口 WaitForSingleObject(pi.hProcess, INFINITE); // 关闭进程和线程句柄 CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0;}
2、获取指定进程PID
在C++中,获取Windows进程的PID(进程标识符)通常涉及到使用Windows API函数来枚举系统中的进程,并检查每个进程的名称或其他属性以确定所需的PID。一个常用的函数是Toolhelp32Snapshot,它允许你获取一个快照,其中包含了当前系统中所有进程的信息。
以下是一个简单的示例,展示了如何使用Toolhelp32Snapshot和PROCESSENTRY32结构来获取特定进程名称的PID:
cpp
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
DWORD GetProcessIdByName(const std::wstring& processName) {
DWORD pid = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe32)) {
do {
if (std::wstring(pe32.szExeFile) == processName) {
pid = pe32.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
}
return pid;
}
int main() {
std::wstring processName = L"notepad.exe"; // 要查找的进程名称
DWORD pid = GetProcessIdByName(processName);
if (pid != 0) {
std::wcout << L"Process ID for " << processName << L" is: " << pid << std::endl;
}
else {
std::wcout << L"Process not found." << std::endl;
}
return 0;
}
Process ID for notepad.exe is: 9428
3、结束进程
结束进程在计算机操作系统中指的是关闭或终止正在运行的程序或进程。当多个程序和进程在系统中同时运行时,为了控制和管理这些进程,操作系统提供了一些工具和方法来结束不需要或有问题的进程。结束进程的目的通常是为了解决以下问题:
**占用过多资源:**某个进程可能因为异常或错误而占用过多的CPU、内存或磁盘资源,导致其他进程无法正常运行。这时可以选择结束该进程,以释放资源并修复问题。
**响应缓慢或无响应:**某个进程可能会因为死锁、死循环或其他原因而长时间无响应,导致用户无法操作或其他进程受阻。结束该进程可以恢复系统的正常运行。
**危险或恶意程序:**某些程序可能会具有危险性或恶意行为,如病毒、恶意软件或未经授权的访问。这时,结束该进程可以避免该程序进一步对系统造成损害。
在C++中,关闭Windows进程通常涉及到使用Windows API函数,比如TerminateProcess,或者通过发送特定的信号给进程来请求其优雅地关闭。然而,更常见和推荐的做法是,如果可能的话,让进程自己处理关闭逻辑,比如通过接收一个退出信号或调用特定的关闭函数。
如果你确实需要从外部关闭一个进程,你可以使用TerminateProcess函数。这个函数会立即终止指定的进程及其所有线程。下面是一个简单的示例:
cpp
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
bool CloseProcessByPID(DWORD pid) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProcess == NULL) {
std::cerr << "OpenProcess failed (" << GetLastError() << ")." << std::endl;
return false;
}
if (!TerminateProcess(hProcess, 999)) { // 999是退出码,可以自定义
std::cerr << "TerminateProcess failed (" << GetLastError() << ")." << std::endl;
CloseHandle(hProcess);
return false;
}
CloseHandle(hProcess);
return true;
}
int main() {
DWORD pid = 9428; // 这里替换为你要关闭的进程的PID
if (CloseProcessByPID(pid)) {
std::cout << "Process with PID " << pid << " has been terminated." << std::endl;
}
else {
std::cout << "Failed to terminate process with PID " << pid << "." << std::endl;
}
return 0;
}
Process with PID 9428 has been terminated.
4、进程枚举
在C++中,枚举Windows进程通常涉及到使用Windows API函数来获取系统中当前运行的所有进程的列表。CreateToolhelp32Snapshot函数是完成这项任务的一个常用方法,它允许你创建一个快照,其中包含了系统的状态信息,比如正在运行的进程。
下面是一个使用CreateToolhelp32Snapshot和PROCESSENTRY32结构来枚举Windows进程的示例代码:
#include <windows.h> #include <tlhelp32.h> #include <iostream> #include <vector> bool EnumerateProcesses(std::vector<DWORD>& processIds) { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == INVALID_HANDLE_VALUE) { return false; } PROCESSENTRY32 pe32; pe32.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, &pe32)) { CloseHandle(hSnapshot); return false; } do { processIds.push_back(pe32.th32ProcessID); } while (Process32Next(hSnapshot, &pe32)); CloseHandle(hSnapshot); return true;}int main() { std::vector<DWORD> processIds; if (EnumerateProcesses(processIds)) { std::cout << "Enumerated processes:\n"; for (const auto pid : processIds) { std::cout << "PID: " << pid << std::endl; } } else { std::cerr << "Failed to enumerate processes." << std::endl; } return 0;}
Enumerated processes:
PID: 0
PID: 4
PID: 100
PID: 432
PID: 704
PID: 808
PID: 832
PID: 904
PID: 912