如何获取子进程的输出

联邦学习代码解读,超详细 联邦学习伪代码 损失函数使用方法 1 optimizer = optim.Adam(model.parameters()) 2 fot epoch in range(num_epoches): 3 train_loss=0 4 for step,(seq, label) in enumerate(data_loader): 5 # 损失函数 6 loss = criterion(model(seq), label.to(device) 阅读详情

 经常看到论坛中有人问到当用Process组件启动新的进程后,如何获取它的输出的问题。采取将子进程的输出定向到一个临时文件中,当然也可以解决问题。但是这样每次父进程从临时文件中获取信息后,还要删除该临时文件,毕竟比较麻烦。其实,Process提供了几个属性可以获取输出。在.net框架sdk的帮助文档里面就有这方面的例子,但是对于如何同时获取错误输出和标准输出方面没有给出具体代码,本文将给出实例并对管道的特性作一些说明。

 

一、获取子进程标准输出和错误输出的的方法:

 

我们写一个小程序p2.cs,用它来产生标准输出和错误输出。

 

//p2.cs代码如下:

using System;

class class1

{

 public static void Main()

 {

  int i = 0;

  string s1 = String.Format("out:{0,4}--------------------------------------------------",i);

  System.Console.Out.WriteLine(s1);

  string s2 = String.Format("err:{0,4}**************************************************",i);

  System.Console.Error.WriteLine(s2);

 }

}

 

编译成p2.exe

 

获取子进程的标准输出和错误输出的源程序

 

//p1.cs

....

Process p = new Process("p2.exe");

 

p.StartInfo.UseShellExecute = false;  //指定不使用系统的外壳程序,而是直接启动被调用程序本身

 

p.StartInfo.RedirectStandardOutput = true;  //只有将此属性设为true,才能通过管道获取子进程输出

 

p.StartInfo.RedirectStandardError = true;

 

p.Start();  //启动子进程

 

string output = p.StandardOutput.ReadToEnd(); //读取标准输出

 

string error = p.StandardError.ReadToEnd(); //读取错误输出

 

p.WaitForExit(); //等待子进程执行完毕

 

...

 

上例中,父进程启动子进程后,就等待着从管道中取走标准输出,取走全部标准输出后取走错误输出。我们运行起来没有任何错误。但是一旦我门增加p2.exe中的标准输出和错误输出的字节数:

 

for(i=0;i<200;i++)

 System.Console.Out.WriteLine(s1);

for(i=0;i<200;i++)

 System.Console.Error.WriteLine(s2);

 

编译后,再运行,就会发现父进程和子进程出现了死锁,只有强行关闭才能终止进程。

 

二、管道:

 

Process 组件通过管道与子进程进行通讯。如果同时重定向标准输出和标准错误,然后试图读取它们,当管道被填满时候就会出现问题。上例中,父进程只有读完了所有的标准输出才能读错误输出,而子进程的标准输出每当把管道填满时候,父进程都会取走,子进程接着向管道输出后续的标准输出。这都运行的很好。可是当子进程执行到输出错误输出的时候,由于子进程还没有运行结束,它的标准输出流就不会处于结束状态(虽然在我们的例子中它的200次循环的标准输出已经执行完毕),这就导致父进程中的ReadToEnd()方法不会执行完毕,所以父进程中的p.StandardError.ReadToEnd()无法执行,从而管道中的错误输出无法被读取,子进程的后续错误输出无法写入管道,最终子进程和父进程彼此无限等待,出现了阻塞情况。

 

子进程通过检查管道中最后一个字节是否被取走,来决定是否输出后续内容。也就是说,如果管道缓冲区中最后一个字节之前的所有内容都被取走,子进程仍然会处于等待中;如果前面所有字节都没有取走,但最后一个字节内容被取走,子进程会继续向管道里输出后续内容,当然这样只能输出一字节到管道中最后位置。

 

我们如果把p1.cs中的string output = p.StandardOutput.ReadToEnd()改为:

 

 for(int i=0;i<200*60;i++)

  Console.Write((char) p.StandardOutput.Read());

 

就不会出现死锁情况。因为当获取标准输出的循环执行完后,会接着执行获取错误输出的语句,而不需等待标准输出流的结束。但是这种方法毫无实际意义,因为实际中,我们并不可能像本例中知道标准输出会有多少字节。

 

三、用多线程分别获取标准输出和错误输出

 

对于这种情况,.net框架文档中建议这样解决:创建两个线程,以便应用程序可以在单独的线程上读取每个流的输出。下面给出例子:

 

//p1.cs:

...

class class1

{

   .....

   public static void Main()

   {

 ProcessStartInfo pi = new ProcessStartInfo();

 pi.FileName = @"c:/p2.exe";

 pi.UseShellExecute = false;

 pi.RedirectStandardOutput = true;

 pi.RedirectStandardError = true;

 System.Diagnostics.Process p = new Process();

 p.StartInfo = pi;

 p.Start();

 tout t1 = new tout(p);

 terr t2 = new terr(p);

 Thread thread1 = new Thread(new ThreadStart(t1.Read));

 Thread thread2 = new Thread(new ThreadStart(t2.Read));

 thread1.Start();

 thread2.Start();

 p.WaitForExit();

 Console.WriteLine("p2.exe结束");

   }

}

class tout

{

 Process p;

 public tout(Process p)

 {

  this.p = p;

 }

 public void Read()

 {

  int a = -1;

  while((a = p.StandardOutput.Read()) > 0)

  {

   Console.Write( ((char) a).ToString() );

  }

  Thread.CurrentThread.Abort();

  return;

 }

}

class terr

{

 Process p;

 public terr(Process p)

 {

  this.p = p;

 }

 public void Read()

 {

  int a = -1;

  while((a = p.StandardError.Read()) > 0)

  {

   Console.Write(((char) a).ToString());

  }

  Thread.CurrentThread.Abort();

  return;

 }

}

 

精雕软件(JDpaint) 5.5 绿色版 精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版 立即下载

相关推荐

天祥TX-1C单片机开发板-秒表程序

郭天祥TX-1C开发板实现秒表程序 附开发板图片和原理图 代码 #include <reg52.h> sbit key1=P3^4; //按键S2 sbit key2=P3^5; //按键S3 sbit U1=P2^6; //LED位选 sbit U2=P2^7; //LED片选 unsigned char code ledchar[]={ /...

Run_long_road 3511

C++--问题24--进程的上下文切换

C++--问题21--进程的上下文切换 PCB 是进程存在的唯一标识,这意味着一个进程的存在,必然会有一个 PCB,如果进程消失了,那么 PCB 也会随之消失。 PCB 具体包含信息:

数组越界,数组进栈 1769

手把手教你用THS4551搭建全差分放大器电路(附ADC驱动实战)

本文详细介绍了如何使用TI的THS4551全差分放大器搭建高性能ADC驱动电路,涵盖芯片选型、电路配置、PCB布局及实战调试等关键环节。THS4551凭借其优异的共模抑制比和宽电源电压范围,成为驱动16位及以上精度ADC的理想选择,特别适合工业应用场景。

weixin_30338481的博客 279

Windows 下C++ 利用管道通信获得子进程的输出

下面是父进程的代码,注意创建管道时CreatePipe()函数的第三个参数一定要有,否则从管道中度不输数据 #include <iostream> #include <windows.h> #include <tchar.h> using namespace std; int main() { STARTUPINFO si = {0}; PROCESS_...

糖炒栗子的博客 1980

芯片详解——AD7606

AD7606详解

weixin_45661757的博客 5017

【AAOS】【源码分析】用户管理(五)-- MUMD介绍

MUMD(多用户多屏显示)是Android Automotive OS为车载多乘员场景设计的功能,支持不同座位用户独立操作各自屏幕。

码农的历程 1510

windows下,C++中调用命令行并且获取命令行的输出

最近在做C++时遇到了一个棘手的问题,我需要获取组策略中的密码配置策略,但是本地用户没有权限。只能使用转调命令行来获取密码配置的输出,因此对C++中调用命令行的几种方式进行了汇总整理。 1. system,system函数在不同平台下都有实现,但是system函数无法获取cmd执行的结果 #include "stdafx.h" /** * @brief 通过system调用命令行 */ void cmdSystem(const std::string& cmdLine) { syste

ai_admin的博客 1万+

使用Termux在Android设备上编译运行SpecCPU2006

SPEC2006搭配Termux,竟然还能这么玩?!

菜菜的菜园子 2958

如何执行,获取子进程的输出

     经常看到论坛中有人问到当用Process组件启动新的进程后,如何获取它的输出的问题。采取将子进程的输出定向到一个临时文件中,当然也可以解决问题。但是这样每次父进程从临时文件中获取信息后,还要删除该临时文件,毕竟比较麻烦。其实,Process提供了几个属性可以获取输出。在.net框架sdk的帮助文档里面就有这方面的例子,但是对于如何同时获取错误输出和标准输出方面没有给出具体代码,本文将给出

肄若芸(yiruoyun)的专栏 1350

基于TIA博途的一阶滞后滤波+中位值滤波+堆栈平均值滤波算法SCL语言程序(封装FB库)

基于TIA博途的一阶滞后滤波+中位值滤波+堆栈平均值滤波算法SCL语言程序(封装FB库)

Robot_PLC_HMI_Automation 2177

芒果YOLO11改进44:主干Backbone篇之MobileViT::结合最新 ICLR2022 顶会|轻量通用的MobileViT结构(一)Transformer,轻量级、通用且移动友好的视觉转换

MobileViT::结合最新 ICLR2022 顶会|轻量通用的MobileViT结构(一)Transformer,轻量级、通用且移动友好的视觉转换

包括YOLOv5、YOLOv7、YOLOv8等模型改进 369

Windows下获取子进程标准输出

需求来源:项目上有用到需要获取ffmpeg的命令输出,进行解析,而后添加成进度条的形式表现出来 因此写了个获取子进程输出的通用工具代码 实现原理: 创建可继承的匿名管道 将其中的写管道,作为createprocss的参数传入,替换子进程的标准输出 调用readfile从读管道进行循环读取内容 代码如下: #include <windows.h> #include <tchar...

冰糖葫芦的夏天的博客 2923

PCL 使用点云创建数字高程模型DEM【2025最新版】

使用点云创建数字高程模型DEM,并将结果保存为高程图像。博客长期更新,本文最近更新时间为:2025年9月15日。

点云侠的博客 2294

python实时获取子进程输出_Python 从subprocess运行的子进程中实时获取输出的例子...

有些时候,我们需要将某些程序放到子进程中去运行,以达到整合系统的目的。在Python中,一个非常好的选择就是使用subprocess模块,本模块为开辟子进程去执行子程序提供了统一的接口,更加便于学习和使用。同时,对于在子进程里的程序,我们希望能够实时获取其输出,以在主进程中打印相关信息,使我们能够了解当前子程序的执行进度。对此,subprocess模块也提供了相应的参数,能够将子程序的标准输出和标...

weixin_39704727的博客 755

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

如何获取包含管道的 Python 子进程命令的输出?

在这个例子中,我们首先构建了一个命令,该命令会通过 SSH 连接到任务的服务器上,并运行 `ps aux | grep python` 命令。然后,我们创建了一个子进程,获取了这个命令的输出,并根据这个输出来确定任务的执行状态。例如,如果某个任务的服务器上没有运行的任务,那么这个任务的执行状态就是 "空闲"。如果某个任务的服务器上有正在运行的任务,但是这些任务并没有被 "python" 这个命令创建,那么这个任务的执行状态就是 "其他语言的任务"。# 创建一个子进程,该子进程会运行包含管道的命令。

427

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

python实时获取子进程输出_python - 使用子进程获取实时输出

python - 使用子进程获取实时输出我正在尝试为命令行程序(svnadmin verify)编写一个包装器脚本,它将为操作显示一个很好的进度指示器。 这要求我能够在输出后立即查看包装程序的每一行输出。我想我只是使用exec*执行程序,使用Popen,然后在进入时读取每一行并相应地对其进行操作。 但是,当我运行以下代码时,输出似乎在某处缓冲,导致它出现在两个块中,第1行到第332行,然后是33...

weixin_39620151的博客 1449

Python:从subprocess运行的子进程中实时获取输出

有些时候,我们需要将某些程序放到子进程中去运行,以达到整合系统的目的。在Python中,一个非常好的选择就是使用subprocess模块,本模块为开辟子进程去执行子程序提供了统一的接口,更加便于学习和使用。   同时,对于在子进程里的程序,我们希望能够实时获取其输出,以在主进程中打印相关信息,使我们能够了解当前子程序的执行进度。对此,subprocess模块也提供了相应的参数,能够将子程序的标...

6万+

# 使用subprocess模块调用子进程并获取输出

使用subprocess模块调用子进程并获取输出 从python2.4开始,内置的subprocess模块可以创建子进程并连接子进程的标准输入/输出/错误,因此可以用来执行外部程序并获取执行结果和输出。本文示例基于Python2.7,转为Python3代码时需要考虑对bytes类型返回值的decode()转码。 Popen类方法 subprocess模块通过Popen类完成创建子进程并与其交互的功...

灵感点滴的分享 2559

java 父进程获取子进程的输出 ,父子进程通信,(标准输入输出)

应用场景:B进程负责处理数据,结果输出在标准输出中,A进程作为B的父进程去启动B进程,A可以获取到B进程的stdout,stderr.这样做的好处是解耦,假设B进程是java语言开发,na'm

笔生花的博客 1472

获取子进程的输出

CStdioFile file; CString strRead; CStringList stacklist; int itemID = 0; CDebugTombstoneDlg * pthis = (CDebugTombstoneDlg *) lpParameter; HANDLE hReadPipe, hWritePipe; SECURITY_ATTRIBUTES

一介渔夫 2708
上一篇: 路径,文件,目录,I/O常见操作汇总
下一篇: 深入探讨如何在 C# 中使用 Win32 和其他现有库
Python
博客等级 码龄26年 1973粉丝 1567原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值