当前位置: 首页 > news >正文

【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁

📝个人主页🌹:Eternity._
⏩收录专栏⏪:Linux “ 登神长阶 ”
🌹🌹期待您的关注 🌹🌹

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

❀Linux进程间通信

  • 📒1. 进程间通信介绍
  • 📚2. 什么是管道
  • 📜3. 匿名管道
    • 🌞fork共享管道原理
    • 🌙结合文件描述符
    • ⭐站在内核角度
  • 📝4. 管道的读写情况与特点
    • 🎈管道的读写情况
    • 🎩管道的特性
  • 📖5. 总结


前言:当提及Linux系统中的进程间通信(IPC),管道(Pipes)无疑是最基础且广泛使用的一种机制。作为匿名通信的典范,管道为进程间数据交换提供了一个简单而有效的途径。在这个信息飞速传递的时代,掌握Linux管道的使用不仅是理解操作系统底层通信原理的关键一步,也是提升软件开发效率、构建复杂应用系统的必备技能

本篇文章将带您深入探索Linux进程间匿名通信的管道机制。我们将从管道的基本概念出发,逐步揭开其背后的工作原理,并通过实例演示如何在实际编程中创建、使用和维护管道。无论您是初学者,希望建立对Linux IPC的初步认识;还是经验丰富的开发者,渴望在现有基础上进一步精进;亦或是对系统编程充满好奇的学习者,渴望深入了解操作系统内部的奥秘,本文都将为您提供丰富的知识和实用的指导

我们将详细介绍管道的创建过程、数据读写操作、管道的生命周期管理以及常见的使用场景。 同时,我们还会探讨管道在并发编程中的表现,分析其在多进程环境下的行为特性,并提供相应的优化策略。通过理论与实践相结合的方式,相信您能够全面掌握Linux进程间匿名通信的管道技术,为您的软件开发之路增添一份坚实的力量

让我们一同踏上这段探索之旅,揭开Linux管道的神秘面纱,领略其在进程间通信中的独特魅力!


📒1. 进程间通信介绍

进程间通信(Interprocess communication,IPC)是指在不同的进程之间传播或交换信息。由于进程的用户空间是互相独立的,一般而言不能互相访问,但存在一些双方都可以访问的介质或系统空间来实现通信

  • 原理: 进程间通信主要依赖于双方都可以访问的介质或系统空间。这些介质包括共享内存区、系统空间以及双方都可以访问的外设(如磁盘上的文件、数据库中的表项等)。然而,广义上的通过这些方式进行的通信一般不算作“进程间通信”。进程间通信更常见的是通过一组编程接口来实现,这些接口允许程序员协调不同的进程,使它们能在一个操作系统里同时运行,并相互传递、交换信息

  • 必要性: 即使只有一个用户发出要求,也可能导致一个操作系统中多个进程的运行。这些进程之间必须互相通信,以协调它们的行为和共享资源。进程间通信使得一个程序能够在同一时间里处理许多用户的要求


📚2. 什么是管道

  • 管道是Unix中最古老的进程间通信的形式
  • 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”

在这里插入图片描述

管道分为:匿名管道和命名管道,本篇我们主要来了解一下匿名管道


📜3. 匿名管道

匿名管道是Linux中一种非常基础的进程间通信(IPC)方式,其本质上是一种内存级的文件,专门用于父子进程间或具有亲缘关系的进程间的通信

创建匿名管道

#include <unistd.h>//功能:创建一无名管道
//原型
int pipe(int fd[2]);//参数
//fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
//返回值:成功返回0,失败返回错误代码

在这里插入图片描述
实例代码:

#include <iostream>
#include <cassert>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>#define MAX 1024using namespace std;int main()
{// 1. 建立管道int pipefd[2] = {0};int n = pipe(pipefd);assert(n == 0);// 定义 n(void)n;// 查看文件描述符cout << "pipefd[0]: " << pipefd[0] << ", pipefd[1]: " << pipefd[1] << endl;// 2. 创建子进程pid_t id = fork();if(id < 0){perror("fork");return 1;}// 子写,父读,// 3. 关闭父子不需要的fd,形成单向通信的管道if(id == 0){// 子进程close(pipefd[0]);// 写入int cnt = 10;while(cnt){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt--;write(pipefd[1], message, strlen(message));cout << "writing cnt: " << cnt << endl;}exit(0);}// 父进程close(pipefd[1]);// 读取char buffer[MAX];while(true){ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}}pid_t rid = waitpid(id, nullptr, 0);if(rid == id){cout << "wait seccess" << endl;}return 0;
}

🌞fork共享管道原理

在这里插入图片描述


🌙结合文件描述符

在这里插入图片描述


⭐站在内核角度

在这里插入图片描述


📝4. 管道的读写情况与特点

🎈管道的读写情况

  1. 正常情况,如果管道没有数据了,读端必须等待,直到有数据为止(写端写入数据)
  2. 正常情况,如果管道被写满了,写端必须等待,直到有空间为止(读端读走数据)

我们让读端一直读,而写端在写入部分文件后让它sleep一段时间,我们这是来观察一下读端的情况

代码示例:(C++):

if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 10000;while(cnt){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt--;write(pipefd[1], message, strlen(message));// 在正常写入一次后,sleep,父进程读取不做修改sleep(4);       }exit(0);
}

在这里插入图片描述


当我们的管道被写满了的时候,写端就不能在进行写入了,我们必须等待读端将数据读取走才能继续往管道里面写入,我们让读端休眠上几面,让写端一直写

代码示例:(C++):

if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 0;while(true){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt++;write(pipefd[1], message, strlen(message));// 在正常写入一次后,sleep,父进程读取不做修改cout << "writing cnt: " << cnt << endl; 	}exit(0);
}

在这里插入图片描述


  1. 写端关闭,读端一直读取,读端会读到read返回值为0,表示读到文件结尾
  2. 读端关闭,写端一直写入,0S会直接杀掉写端进程,通过想目标进程发送SIGPIPE(13)信号,终止目标进程

写端关闭代码示例:(C++):

if(id == 0)
{// 子进程close(pipefd[0]);// 写入int cnt = 0;while(true){char message[MAX];snprintf(message, sizeof(message), "hello father, I am child, pid: %d, cnt: %d", getpid(), cnt);cnt++;write(pipefd[1], message, strlen(message));//sleep(2);cout << "writing cnt: " << cnt << endl;// 在写入两次时,我们将子进程的写入关闭if(cnt == 2){close(pipefd[1]);break;}}exit(0);
}// 父进程
close(pipefd[1]);// 读取
char buffer[MAX];
while(true)
{sleep(4);ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);// 当 n == 0 时,代表read已经读到文件结尾了if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}
}

我们这样设计代码,先让子进程写入之后,关闭掉pipefd[1],然后观察父进程是否会打印,我们需要的代码

在这里插入图片描述


读端关闭代码示例:(C++):

// 父进程
close(pipefd[1]);// 读取
char buffer[MAX];
while(true)
{//sleep(4);ssize_t n = read(pipefd[0], buffer, sizeof(buffer)-1);if(n == 0){cout << "child qiut, read tail" << endl;break;}else if(n > 0){buffer[n] = 0; // '\0', 当作字符串cout << getpid() << ": " << "child say: " << buffer << " to me!" << endl;}cout << "father return val(n)" << n << endl;sleep(1);// 打印一次后,我们退出循环    break;
}// 关闭 pipefd[0],停止读取
cout << "close point read" << endl;
close(pipefd[0]);sleep(3);int status = 0;
pid_t rid = waitpid(id, &status, 0);
if(rid == id)
{cout << "wait seccess, exit sig: " << (status&0x7f) << endl;
}

注意:当前状态码 & 0x7f可以查看到最后的退出码

在这里插入图片描述


🎩管道的特性

管道的5种特性

  1. 匿名管道,可以允许具有血缘关系的进程之间进行进程间通信,常用与父子,仅限于此
  2. 匿名管道,默认给读写端要提供同步机制
  3. 面向字节流的入
  4. 管道的生命周期是随进程的
  5. 管道是单向通信的,半双工通信的一种特殊情况

在了解完管道的这些情况和特征后,我们可以利用管道来写一个简单的线程池

线程池代码链接


📖5. 总结

在探索Linux进程间匿名通信的管道机制这一旅程的尾声,我们不禁对Linux操作系统的精妙设计和强大功能有了更深一层的理解。管道,作为进程间通信的基础而又高效的工具,不仅简化了数据在不同进程间的流动过程,还极大地促进了多任务并发执行的灵活性

通过本文的学习,我们见证了管道从创建到使用的全过程,理解了其背后的工作原理,并掌握了如何在实际编程中利用管道来实现进程间的数据交换。从pipe()函数的调用,到文件描述符的分配,再到数据的读写操作,每一个步骤都蕴含着Linux系统设计的智慧与匠心

但Linux提供的进程间通信机制远不止于此。命名管道、消息队列、共享内存、信号量以及套接字等多种IPC方式,各自拥有独特的优势和适用场景。在未来的学习与实践中,我们可以继续深入探索这些机制,以更加灵活多样的方式实现进程间的协同工作

让我们以更加饱满的热情和坚定的信心,继续前行在Linux系统编程的学习之路上!

在这里插入图片描述

希望本文能够为你提供有益的参考和启示,让我们一起在编程的道路上不断前行!
谢谢大家支持本篇到这里就结束了,祝大家天天开心!

在这里插入图片描述

相关文章:

【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux进程间通信 &#x1f4d2;1. 进程间通信介绍&#x1f4da;2. 什么是管道&#x1f4dc;3…...

【力扣 | SQL题 | 每日三题】力扣1148, 1327, 1211, 1174

1. 力扣1148&#xff1a;文章浏览1 1.1 题目&#xff1a; Views 表&#xff1a; ------------------------ | Column Name | Type | ------------------------ | article_id | int | | author_id | int | | viewer_id | int | | view_date …...

【鸿蒙开发】详解GridRowSizeOption的尺寸属性

文章目录 1. 尺寸属性的含义2. 为什么要有这几个属性3. 具体作用4. 如何使用总结 在鸿蒙&#xff08;HarmonyOS&#xff09;开发中&#xff0c;布局的灵活性和适应性对于构建高质量的应用至关重要。 GridRowSizeOption是鸿蒙开发框架提供的一个布局属性&#xff0c;用于定义网…...

Sping源码:三级缓存

目录 一、概念1、三级缓存的作用2、循环依赖的含义 二、代码1、代码下载2、文件功能介绍3、源码分析3.1、找到获取A对象的位置&#xff0c;打断点进行debug操作3.2、一步步找到在A对象中注入B对象的位置3.3、一步步找到B对象注入A对象的位置3.4、往下找到通过三级缓存解决循环依…...

latex有哪些颜色中文叫什么,Python绘制出来

latex有哪些颜色中文叫什么&#xff0c;Python绘制出来 为了展示xcolor包预定义的颜色及其对应的中文名称&#xff0c;并使用Python打印出来&#xff0c;我们可以先列出常见的预定义颜色名称&#xff0c;然后将它们翻译成中文&#xff0c;并最后用Python打印出来。 步骤 列出…...

C语言进程

什么是进程 什么是程序 一组可以被计算机直接识别的 有序 指令 的集合。 通俗讲&#xff1a;C语言编译后生成的可执行文件就是一个程序。 那么程序是静态还是动态的&#xff1f; 程序是可以被存储在磁盘上的&#xff0c;所以程序是静态的。 那什么是进程 进程是程序的执行过…...

C#基础(4)封装——成员方法

前言 我们在上一节学习了关于类的成员变量的使用&#xff0c;甚至也看到了相应的成员方法&#xff0c;我们可以将二者理解为类里面的变量和函数。 如果我这样说你肯定就能很快理解成员方法是什么作用了。 C#中设计成员方法的目的是为了将相关的功能代码组织在一起&#xff0…...

springbot,JWT令牌的使用。实现http请求拦截校验。

JWT 由三部分组成&#xff0c;用点&#xff08;.&#xff09;分隔 Header&#xff08;头部&#xff09; Payload&#xff08;负载&#xff09;Signature&#xff08;签名) 一、原理 Jwt原理其实很简单&#xff0c;在后端首先要有个拦截器&#xff0c;他会拦截所有http请求&…...

【SQL】DDL语句

文章目录 1.SQL通用语法2.SQL的分类3.DDL3.1数据库操作3.2 表操作3.2.1 表操作--数据类型3.2.2 表操作--修改3.2.3 表操作--删除 SQL 全称 Structured Query Language&#xff0c;结构化查询语言。操作关系型数据库的编程语言&#xff0c;定义了一套操作关系型数据库统一标准 。…...

【分页】Spring Boot 列表分页 + javaScript前台展示

后端&#xff1a; 准备好查询实体与分页实体 1、分页工具实体 package com.ruoyi.dms.config;import com.alibaba.nacos.api.model.v2.Result; import lombok.Data;import java.io.Serializable; import java.util.List;/*** author 宁兴星* description: 列表返回结果集*/ …...

「安装」 Windows下安装CUDA和Pytorch

「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…...

c语言基础作业

选择题 1.1、以下选项中,不能作为合法常量的是 __________ A&#xff09;1.234e04 B&#xff09;1.234e0.4C&#xff09;1.234e4 D&#xff09;1.234e0 1.2、以下定义变量并初始化错误的是_____________。 A) char c1 ‘H’ &#xff1b; B) char c1 9…...

uniapp view增加删除线

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…...

[Day 83] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈在物聯網中的應用 區塊鏈技術與物聯網&#xff08;IoT&#xff09;結合&#xff0c;為許多領域提供了強大的解決方案。傳統的IoT架構常面臨數據隱私和安全問題&#xff0c;而區塊鏈的去中心化和加密技術則能有效增強IoT系統的安全性、透明性和效率。本文將探討區塊鏈如何…...

Java ReentrantLock

目录 1 互斥性 2 公平性 3 可重入性 4 获取和释放锁 5 尝试获取锁 6 可中断的锁定 7 条件变量 8 性能 9 使用场景 ReentrantLock 是 Java 提供的一种可重入的互斥锁&#xff0c;位于 java.util.concurrent.locks 包中&#xff0c;它实现了 Lock 接口。这个锁提供了与内…...

【Linux系统编程】第二十六弹---彻底掌握文件I/O:C/C++文件接口与Linux系统调用实践

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、回顾C语言文件接口 1.1、以写的方式打开文件 1.2、以追加的方式打开文件 2、初步理解文件 2.1、C文件接口 3、进一步理…...

数据分析-29-基于pandas的窗口操作和对JSON格式数据的处理

文章目录 1 窗口操作1.1 滑动窗口思想1.2 函数df.rolling2 JSON格式数据2.1 处理简单JSON对象和JSON列表2.1.1 处理简单的JSON结构2.1.2 处理空字段2.1.3 获取部分字段2.2 处理多级json2.2.1 展开所有级别(默认)2.2.2 自定义展开层级2.3 处理嵌套列表JSON3 参考附录1 窗口操作 …...

Ubuntu-WSL2一键设置代理操作

现状&#xff1a; Window11中拥有自己的代理软件 &#xff0c;可以科学上网已在WSL2中安装Ubuntu22.04 需求&#xff1a; Ubuntu-WSL2实现科学上网 实现&#xff1a; 参考&#xff1a;为 WSL2 一键设置代理 Linux 子系统中的网关指向的是 Windows&#xff0c;DNS 服务器指…...

ubuntu命令行连接wifi

在Ubuntu上&#xff0c;你可以通过命令行连接到Wi-Fi网络。以下是详细步骤&#xff0c;主要使用 nmcli 和 nmtui 命令。 方法 1&#xff1a;使用 nmcli nmcli 是 NetworkManager 的命令行界面&#xff0c;用于管理网络连接。以下是使用 nmcli 连接到 Wi-Fi 网络的步骤&#x…...

日常工作第10天:

vim 批量编辑的命令是 移动光标到列首。按键 CtrlV 进入 Visual block 模式&#xff0c;标记你想要进行编辑的列&#xff08;HJKL可以向左下上右移动光标&#xff09;。按键 ShiftI 进入 Insert 模式&#xff0c;在列首输入文本&#xff1b;或者 Shift A&#xff0c;追加文本…...

CNN+Transformer解说

CNN&#xff08;卷积神经网络&#xff09;和Transformer是两种在深度学习领域广泛使用的模型架构&#xff0c;它们在处理不同类型的数据和任务时各有优势。 CNN擅长捕捉局部特征和空间层次结构&#xff0c;而Transformer擅长处理序列数据和长距离依赖关系。 将CNN与Transform…...

jmeter中token测试

案例&#xff1a; 网站&#xff1a;http://shop.duoceshi.com 讲解&#xff1a;用三个接口来讲解 第一个接口code&#xff1a;GET http://manage.duoceshi.com/auth/code 第二个登录接口&#xff1a;http://manage.duoceshi.com/auth/login 第三个接口&#xff1a;http://…...

基于解压缩模块的JPEG同步重压缩检测论文学习

一、论文基本信息&#xff1a; 论文题目&#xff1a;基于解压缩模块的JPEG同步重压缩检测 作者&#xff1a;王金伟1 &#xff0c;胡冰涛1 &#xff0c;张家伟1 &#xff0c;马 宾2 &#xff0c;罗向阳3 &#xff08;1.南京信息工程大学计算机学院、网络空间安全学院&#xf…...

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…...

【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法

一、报错原因 我们使用 make 命令&#xff0c;想要将 text.c 文件编译形成 可执行文件 text 时&#xff0c;报错如下 make: test is up to date. 中文含义&#xff1a;test 文件已经达到最新状态 意思是&#xff1a; test.c 文件里面的 所有源代码都没有修改过&#xff0c;你…...

【FPGA开发】Xilinx FPGA差分输入时钟的使用方法

正文 以前在使用ZYNQ的领航者ZYNQ7020进行FPGA学习时&#xff0c;它们使用的单端50M的输入时钟&#xff0c;在verlog代码编写上比较简单&#xff0c;而现在使用Alinx的AXU3EG开发板时&#xff0c;发现它使用的是200M的差分输入时钟&#xff0c;哪这个时候&#xff0c;输入时钟要…...

面试扩展知识点

1.C语言中分为下面几个存储区 栈(stack): 由编译器自动分配释放堆(heap): 一般由程序员分配释放&#xff0c;若程序员不释放&#xff0c;程序结束时可能由OS回收全局区(静态区): 全局变量和静态变量的存储是放在一块的&#xff0c;初始化的全局变量和静态变量在一块区域&#…...

【经验分享】MyCAT 中间件

学习了一下数据量过大的解决方案,使用 MyCAT 中间件。 MyCAT 可以解决分布式事务、读写分离、主从、分片等一系列MySQL集群和分布式问题。 整体过程可以概括为拦截 - 分发 - 响应 例如设置 MyCAT 分片规则为每500万条数据就换一个数据库存储。 分库分表的中心思想都是将数据…...

Kotlin:1.8.0 的新特性

一、概述 Kotlin 1.8.0版本英语官方文档 Kotlin 1.8.0 中文官方文档 The Kotlin 1.8.0 release is out and here are some of its biggest highlights: Kotlin 1.8.0发布了&#xff0c;下面是它的一些亮点: JVM 平台新增实验性函数&#xff1a;递归复制或删除目录内容改进了 …...

深度学习之开发环境(CUDA、Conda、Pytorch)准备(4)

目录 1.CUDA 介绍 1.1 CUDA 的基本概念 1.2 CUDA 的工作原理 1.3 CUDA 的应用领域 2. 安装CUDA 2.1 查看GPU版本 2.2 升级驱动&#xff08;可选&#xff09; 2.3 查看CUDA版本驱动对应的支持的CUDA ToolKit工具包 2.4 下载Toolkit 2.5 安装&#xff08;省略&#xff0…...

做地方黄页网站/怎么进行网络营销

近日&#xff0c;阿里云一站式应用研发平台EMAS 2.0正式发布&#xff0c;本次将全新发布包括Serverless、低代码开发平台Mobi、AI工具箱、业务组件等产品服务&#xff0c;同时推出面向中小微企业和开发者的免费套餐扶持计划。开发者可在云时代以更低成本、更便捷地完成应用的开…...

濮阳河南网站建设/网络营销推广要求

Push-Pull推挽输出Open-Drain开漏输出原理输出的器件是指输出脚内部集成有一对互补的MOSFET&#xff0c;当Q1导通、Q2截止时输出高电平&#xff1b;而当Q1截止导通、Q2导通时输出低电平开漏电路就是指以MOSFET的漏极为输出的电路。指内部输出和地之间有个N沟道的MOSFET(Q1)&…...

如何把网站主关键词做到百度首页/网上做广告推广

MySQL 有一个和优秀的语法 create table ... like &#xff0c; 可以快速复制一张表&#xff0c;创建其副本。 PostgreSQL 也有类似的语法&#xff0c;而且更加灵活&#xff0c;不过要注意些细节。先来看看MySQL 语法&#xff1a; create table ... like原始表T1&#xff0c;结…...

国内it外包龙头企业/衡阳seo优化首选

2019独角兽企业重金招聘Python工程师标准>>> Sublime Text http://www.sublimetext.com 官网 http://www.sublimetext.com/2 官网 http://www.sublimetext.com/3 官网 1、插件安装 直接安装下载插件&#xff0c;解压至Packages文件夹中。在这里可以打开Packages文件…...

盐城有没有做网站吗/seo是免费的吗

作为程序员&#xff0c;相较于其它行业的人们面试的时候有个很痛苦的问题就是&#xff0c;很注重基础的考察&#xff0c;特别是数据结构基础的考察&#xff0c;不管你经验多么的丰富&#xff0c;特别是职业生涯中后期侧重于架构或者更上层的开发&#xff0c;你往往会忽略了基础…...

怎样自己开网站赚钱/公众号免费推广平台

// 02ProcessList.cpp文件 #include "stdafx.h" #include <windows.h> #include <tlhelp32.h> // 声明快照函数的头文件 int main(int argc, char* argv[]) { PROCESSENTRY32 pe32; // 在使用这个结构之前&#xff0c;先设置它的大小 pe32.dwSize …...