针对“VC++中进程与多进程管理的方法详解”的完整攻略,我给出以下详细内容:
VC++中进程与多进程管理的方法详解
1. 进程和多进程的概念
进程是一个正在运行的程序的实例,它包含了程序代码和当前正在执行的程序状态。每一个进程都有一个唯一的进程标识符(PID)来区分自己和其他进程。在Windows系统中,每个进程有自己的地址空间、栈、寄存器和堆。
多进程是指同时运行多个进程的操作系统环境。在多进程系统中,每个进程都是独立的,它们各自拥有自己的独立的内存空间和资源。
2. 进程的创建与管理
在VC++中,可以使用CreateProcess函数创建一个新的进程。这个函数的原型如下:
BOOL CreateProcess(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
其中,参数含义如下:
- lpApplicationName:指向可执行文件的名称;
- lpCommandLine:传递给可执行文件的命令行参数,如果没有则置为NULL;
- lpProcessAttributes:进程安全属性,默认为NULL;
- lpThreadAttributes:线程安全属性,默认为NULL;
- bInheritHandles:指定进程句柄是否可以被继承,一般为FALSE;
- dwCreationFlags:指定进程的标志,如CREATE_SUSPENDED可以让进程挂起,方便进行调试等操作;
- lpEnvironment:传递给进程的环境变量;
- lpCurrentDirectory:当前工作目录;
- lpStartupInfo:关于新进程的启动信息,如窗口大小、标题等信息;
- lpProcessInformation:返回新建进程相关的信息,如PID和句柄。
下面是一个示例代码:
#include <Windows.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// CreateProcess参数
TCHAR szCommandLine[] = _T("Calc.exe");
BOOL bRet = CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if (!bRet)
{
_tprintf(_T("Create process failed, error code = %d"), GetLastError());
return -1;
}
// 关闭进程和线程句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
3. 多进程间的通信
多进程之间的通信可以使用几种方式,如:
- 文件映射;
- 匿名管道;
- 共享内存;
- 消息队列;
- 命名管道;
- 窗口消息传递。
这里以匿名管道和共享内存为例进行说明。
3.1. 匿名管道
匿名管道是一种可用于进程间通信的机制,它是一条单向的数据通道。在Windows操作系统中,可以使用CreatePipe函数创建匿名管道,然后使用WriteFile和ReadFile向其中写入和读取数据。
下面是一个示例代码:
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
void ChildProc(HANDLE hRead)
{
char chBuf[256];
DWORD dwReadBytes;
// 从管道中读取数据
if (ReadFile(hRead, chBuf, sizeof(chBuf), &dwReadBytes, NULL))
{
printf("Child process read from pipe: %s\n", chBuf);
}
else
{
printf("Read from pipe failed, error code = %d", GetLastError());
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hRead, hWrite;
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&sa, sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
// 创建匿名管道
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
printf("Create pipe failed, error code = %d\n", GetLastError());
return -1;
}
if (!SetHandleInformation(hRead, HANDLE_FLAG_INHERIT, 0))
{
printf("Set handle information failed, error code = %d\n", GetLastError());
return -1;
}
// 创建子进程
TCHAR szCommandLine[] = _T("ChildProcess.exe");
BOOL bRet = CreateProcess(NULL, szCommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (!bRet)
{
printf("Create process failed, error code = %d\n", GetLastError());
return -1;
}
// 向管道中写入数据
char szMsg[] = "Hello, child process!";
DWORD dwWrittenBytes;
if (WriteFile(hWrite, szMsg, sizeof(szMsg), &dwWrittenBytes, NULL))
{
printf("Parent process write to pipe: %s\n", szMsg);
}
else
{
printf("Write to pipe failed, error code = %d", GetLastError());
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(hRead);
CloseHandle(hWrite);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
注意:匿名管道只支持单向通信,如果需要双向通信,则需要创建两个管道。
3.2. 共享内存
共享内存是一种可以在不同进程之间共享数据的机制,可以通过CreateFileMappign和MapViewOfFile函数创建和访问共享内存。
下面是一个示例代码:
#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#define BUF_SIZE 256
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hMapFile;
LPCTSTR pBuf;
char szMsg[] = "Hello, shared memory!";
TCHAR szMapName[] = _T("Local\\MyMap");
// 创建映射文件句柄
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, szMapName);
if (hMapFile == NULL)
{
printf("CreateFileMapping failed, error code = %d\n", GetLastError());
return -1;
}
// 将共享内存映射到进程的地址空间
pBuf = (LPTSTR)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
if (pBuf == NULL)
{
printf("MapViewOfFile failed, error code = %d\n", GetLastError());
CloseHandle(hMapFile);
return -1;
}
// 向共享内存中写入数据
CopyMemory((PVOID)pBuf, szMsg, strlen(szMsg) * sizeof(char));
printf("Parent process write to shared memory: %s\n", pBuf);
// 关闭句柄和映射
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0;
}
另外,如果需要多个进程同时访问共享内存,则需要先创建一个命名的共享文件映射对象。共享内存仅仅是一个内存区域,为了让多个进程访问它,需要让每个进程都访问同一个物理内存区域。命名对象可以被多个进程共享,进程可以打开同一个命名对象,以便访问共享内存。这样创建的共享内存才能安全地让多个进程同时访问。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:VC++中进程与多进程管理的方法详解 - Python技术站