使用Creatprocess创建子进程,并重定向stdin,stdout时子进程不能读到参数的问题

使用Creatprocess创建子进程,并重定向stdin,stdout时子进程不能读到参数的问题


毕业设计中遇到的一个问题,要求完成一个基于socke网络编程,多线程,多进程的代码在线提交评判系统,在服务器端要实现将提交的代码(主要是window控制台程序)完成编译,运行,评分。(绝壁是我导师不想改作业!)
但是代码中一些需要键盘键入的数据(cin>>a;这种语句),只能通过重定向标准stdin模拟键盘输入,再通过重定向标准stdout将控制台输出返回给父进程,这个过程可以参考msdn文章 Creating a Child Process with Redirected Input and Output
通过STARTUPINFO结构的CreateProcess()API使您能够重定向基于子控制台的进程的标准句柄。如果dwFlags成员设置为STARTF_USESTDHANDLES,则以下STARTUPINFO成员指定基于子控制台的进程的标准句柄:

  siStartInfo.hStdError = g_hChildStd_OUT_Wr;
  siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
  siStartInfo.hStdInput = g_hChildStd_IN_Rd;

但里面有个坑搞了我一天,就是使用下面两句,无法将参数传递给子进程,导致子进程卡在cin语句处,无法正常结束返回结果,就创造了个僵尸进程。

  bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
  bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL);

查了很久的资料,最后有个老哥给我推荐了个msdn文章How to spawn console processes with redirected standard handles,读完之后豁然开朗,其实就是缓冲区的问题,有些提交的代码中输入输出语句没有添加<<endl,就会导致缓冲区不能及时清空。

文章大概意思是 :使用此类C运行时函数(如printf()和fprintf())的子进程在重定向时可能会表现不佳。 C运行时函数维护单独的IO缓冲区。重定向后,可能不会在每次IO调用后立即刷新这些缓冲区。结果,不会立即刷新到printf()调用的重定向管道的输出或getch()调用的输入,并且会延迟,有时会发生无限延迟。如果子进程在每次调用C运行时IO函数后刷新IO缓冲区,则可以避免此问题。只有子进程可以刷新其C运行时IO缓冲区。进程可以通过调用fflush()函数来刷新其C运行时IO缓冲区。

解决方法很简单,就在调用readfile和writefile函数时加一条==fflush(NULL);==语句,把缓存中的东西全flush出来就好了!!!!

发布了1 篇原创文章 · 获赞 0 · 访问量 12
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览