VC++中进程与多进程管理的方法详解

针对“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技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 关于reactjs:何时使用react的“componentdidupdate”方法

    以下是关于“关于ReactJS:何时使用React的“componentDidUpdate”方法”的完整攻略,包含两个示例。 关于ReactJS:何时使用的“componentUpdate”方法 React是一个流行的JavaScript库,用于构建用户界面。在React中,我们可以使用“componentDidUpdate”方法处理组更新后的操作。以下是关…

    other 2023年5月9日
    00
  • Android Beam 文件传输失败分析与解决方法

    Android Beam 文件传输失败分析与解决方法 问题描述 在使用 Android Beam 进行文件传输时,有时会遇到传输失败的问题。该问题的具体表现为,在两个设备相互对接并尝试传输文件时,触碰成功后没有出现文件传输界面,或者传输界面出现后传输一段时间后失败,提示“文件传输失败”。 问题分析 从提示信息来看,文件传输过程中出现了错误,但具体的错误原因不…

    other 2023年6月26日
    00
  • linux下安装numpy

    在Linux下安装NumPy,可以按照以下步骤操作: 步骤1:安装pip NumPy是一个Python库,因此我们需要先安装pip,它是Python的包管理器。在大多数Linux发行版中,pip已经预装了。如果您的系统上没有pip,请按照以下步骤安装: 打开终端并输入以下命令: bash sudo apt-get update sudo apt-get in…

    other 2023年5月6日
    00
  • jmeterjdbcrequest使用详解

    以下是详细讲解“jmeterjdbcrequest使用详解的完整攻略”: jmeterjdbcrequest使用详解 jmeterjdbcrequest是JMeter中用于执行JDBC请求的组件,可以用于测试数据库的性能和稳定性。本攻略将介绍jmeterjdbcrequest的使用方法和常用功能。 步骤一:添加JDBC驱动 在使用jmeterjdbcrequ…

    other 2023年5月10日
    00
  • vue axios封装及API统一管理的方法

    下面介绍一下“Vue axios封装及API统一管理的方法”的完整攻略。 一、为什么需要封装及统一管理API 在Vue项目中使用axios发送HTTP请求是非常常见的,而每次发送请求时,都需要编写一大堆繁琐的代码,例如设置请求头、处理错误、在请求完成后进行数据处理等等。 同时,在一个大型项目中,可能会存在多个人协作开发,每个人都有可能编写自己的API请求函数…

    other 2023年6月25日
    00
  • ajaxControlToolkit AutoCompleteExtender的用法

    首先,在使用AjaxControlToolkit中的AutoCompleteExtender之前,需要确保已经安装并引用了AjaxControlToolkit。可以通过NuGet Package Manager来安装: Install-Package AjaxControlToolkit 安装完成后,在页面中引入AjaxControlToolkit: &lt…

    other 2023年6月26日
    00
  • OpenCV与Qt的环境搭建及Demo

    OpenCV与Qt的环境搭建及Demo的完整攻略 OpenCV是一种开源计算机视觉库,用于处理图像和视频。Qt是一种跨平台的应用程序框架,用于开发图形用户界面。本文将提供OpenCV与Qt的环境搭建及Demo的完整攻略,包括以下内容: 安装OpenCV和Qt 配置Qt项目 示例1:显示图像 示例2:捕获视频 安装OpenCV和Qt 要使用OpenCV和Qt,…

    other 2023年5月6日
    00
  • 单位(Units)

    单位(Units)的完整攻略 单位(Units)是用于测量和表示物理量的标准化量度。在科学和工程领域,我们经常需要使用不同的单位来描述和比较各种物理量。本攻略将详细介绍单位的基本概念、常见的国际单位制(SI)以及如何进行单位转换。 基本概念 单位是用来表示物理量的量度标准。它们提供了一种统一的方式来测量和比较不同的物理量。单位通常由两部分组成:数值和单位符号…

    other 2023年10月15日
    00
合作推广
合作推广
分享本页
返回顶部