程序A:
#include "stdio.h"
int main()
{
int index = 0;
        int i = 0;
for (i = 1; i <9988998; i++) {
printf("Current Count is %d\n", index++); Sleep(10 * 999);
}
}
程序B:
namespace process
{
class Program
{
public static void Main(string[] args)
{
  
       RunCommand1(@"d:\code\test\a.exe", "");
       Console.ReadKey(true);
}

private static void RunCommand1(string s, string arg) {
using (Process process = new System.Diagnostics.Process())  
               {  
                    process.StartInfo.FileName = s;  
                    process.StartInfo.Arguments = arg;  
                    // 必须禁用操作系统外壳程序  
                    process.StartInfo.UseShellExecute = false;  
                    process.StartInfo.CreateNoWindow = true;  
                    process.StartInfo.RedirectStandardOutput = true;                      process.Start();                     // 异步获取命令行内容  
                    process.BeginOutputReadLine();  
                   // 为异步获取订阅事件  
                   process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);  
                    }  
     }  
     
   private static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)  
   {  
       // 这里仅做输出的示例,实际上您可以根据情况取消获取命令行的内容  
   // 参考:process.CancelOutputRead()  
    
       if (String.IsNullOrEmpty(e.Data) == false)  
           //this.AppendText(e.Data + "\r\n");  
        Console.WriteLine(e.Data);
   }    
    public static int RunCommand2(string command, string commandParams)
    {
     var info = new ProcessStartInfo(command, commandParams);
     info.UseShellExecute = false;
     info.RedirectStandardOutput = true;
     info.RedirectStandardError = true;
     var process = Process.Start(info);
     while (!process.HasExited) Thread.Sleep(1000);
     return process.ExitCode;
    }    public static int RunCommand3(string command, string commandParams)
    {
     var info = new ProcessStartInfo(command, commandParams);
     info.UseShellExecute = false;
     info.RedirectStandardOutput = true;
     info.RedirectStandardError = true;
     var process = Process.Start(info);
     var reader = process.StandardOutput;
     var results = new StringBuilder();
     string lineOut;
     while ((lineOut = reader.ReadLine()) != null) {
      //results.AppendLine("STDOUT: " + lineOut);
      Console.WriteLine(lineOut);
     }
     reader = process.StandardError;
     while ((lineOut = reader.ReadLine()) != null) {
      results.AppendLine("STDERR: " + lineOut);
     }
     while (!process.HasExited) Thread.Sleep(1000);
     return process.ExitCode;
    } 
}
}其中,RunCommand1是我自己写的函数,其他的是网上找的代码,这些代码的共同缺点就是会卡死,究其原因,是因为windows的stdout输出是全缓冲的,只有缓冲区满了才会输出,但我要实现的有一行就输出一行,所以一直实现不了,在网上搜了很多,虽然说是异步获取,但和我的函数大同小异,也必须在缓冲区满了后才能输出,现在的问题是程序A我无法修改,上面只是个例子,实际功能比它复杂很多,但原理一样,也没办法把windows的命令行改为行缓冲,各位高手有什么好办法?

解决方案 »

  1.   

    额,那就别printf了呗,反正那边的代码也是你写的,请换成 cout<<"xxxxx"<<endl 方式输出
      

  2.   

    这个缓存区是可以设置的,可以设置成立即输出
    使用函数setvbuf(),请参考:http://www.cplusplus.com/reference/cstdio/setvbuf/?kw=setvbuf
    第三个参数设置成_IONBF即可实现立即输出
      

  3.   

    单独写2个C++程序,reduceBuffer.exe,restoreBuffer.exe,分别是缩减缓存和还原缓存
    依次运行
    reduceBuffer.exe
    a.exe
    restoreBuffer.exe用C#的Process启动管理这些exe的执行顺序