作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 Windows 上创建一个模拟管道的递归 C 函数。
到目前为止,这是我的功能:
static BOOL execute_in_pipe(char (*cmdline)[1024], char *env, int index,
int pipe_length, STARTUPINFO *old_suinfo, HANDLE proc_handles[])
{
//Create new startup info
STARTUPINFO suinfo;
memset(&suinfo, 0, sizeof(suinfo));
suinfo.cb = sizeof(suinfo);
//Create new process info
PROCESS_INFORMATION pinfo;
//Make pipe
HANDLE pipe_out_rd, pipe_out_wr;
if(index > 0) {
HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
if (! CreatePipe(&pipe_out_rd, &pipe_out_wr, &sa, 0))
{
CloseHandle(pipe_out_wr);
CloseHandle(pipe_out_rd);
//res.tag = NATIVE_ERR_PIPE_FAILED;
//return res;
}
//Set output of last process to write handle
if((*old_suinfo).hStdInput == 0) {
(*old_suinfo).hStdInput = hIn;
}
(*old_suinfo).hStdOutput = pipe_out_wr;
(*old_suinfo).dwFlags = STARTF_USESTDHANDLES;
//Set input of this process to read handle
suinfo.hStdInput = pipe_out_rd;
if(index >= pipe_length-1) {
suinfo.hStdOutput = hOut;
}
suinfo.dwFlags = STARTF_USESTDHANDLES;
}
BOOL result = TRUE;
if(index < pipe_length-1) {
result = execute_in_pipe(cmdline, env, index+1, pipe_length, &suinfo, proc_handles);
}
//Return whether creating process succeeds
if(!CreateProcess(NULL, cmdline[index], NULL, NULL,
(pipe_length>1), 0, env, NULL, &suinfo, &pinfo))
{
return FALSE;
}
CloseHandle(pinfo.hThread);
proc_handles[index] = pinfo.hProcess;
return result;
}
我制作了两个 C 程序来测试管道:
种子.c
#include <stdio.h>
int main() {
printf("Hello");
}
追加.c
#include <stdio.h>
#include <string.h>
int main() {
char str[200];
scanf( "%s", str );
printf("%s World!", str);
}
我使用以下方法调用这些函数:
STARTUPINFO suinfo;
HANDLE proc_handles[2];
printf("Starting\n");
char cmdline[2][1024] = {"seed.exe", "append.exe"};
execute_in_pipe(cmdline, 0, 0, 2, &suinfo, proc_handles);
WaitForMultipleObjects(2, proc_handles, TRUE, INFINITE);
调用此函数时,控制台打印出“Starting”,然后等待...永远...
我很确定原因是 scanf 正在尝试读取整行(直到某种分隔符)。当我将 Seed.c 更新为 `printf("Hello\n") 时,它工作得很好。
所以是的,这只是一条规则吗?所有管道进程都应该使用换行符吗?
好的,请调用 seed.exe | append.exe
在命令提示符下效果很好!即使没有换行符!我的代码缺少什么?
编辑:正如一些人所指出的,当所有管道都关闭时,Unix 管道会遇到“End-of-Stream”(不像我最初想象的那样是 EOF)。在测试Unix管道系统时,不会出现这个问题,因此流结束符就像一个分隔符。 Windows 也做了类似的事情吗?如果是这样,我是否必须关闭某些东西才能结束流?
最佳答案
您应该使用命名管道而不是无名管道来执行 I/O 重定向。当服务器的管道句柄关闭时,客户端上的 scanf() 会知道并停止等待换行符。
下面的代码是pascal语言,但并不难理解。
const
BUFSIZE:integer = 512;
Pipename:String = '\\.\pipe\devcpp_run';
InputWrite := CreateNamedPipe(
pAnsiChar(Pipename), // pipe name
PIPE_ACCESS_OUTBOUND, // read/write access
PIPE_TYPE_BYTE or // message type pipe
PIPE_READMODE_BYTE or // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFSIZE, // output buffer size
BUFSIZE, // input buffer size
0, // client time-out
nil); // default security attribute
if InputWrite = INVALID_HANDLE_VALUE then begin
Exit;
end;
InputRead := CreateFile(
PAnsiChar(Pipename), // pipe name
GENERIC_READ,
0, // no sharing
@sa, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
0);
if InputRead = INVALID_HANDLE_VALUE then begin
Exit;
end;
StartupInfo.dwFlags := StartupInfo.dwFlags or STARTF_USESTDHANDLES;
StartupInfo.hStdInput := InputRead;
StartupInfo.hStdOutput := 7; // Undocumented Handle of Console Output
StartupInfo.hStdError := 11; // Undocumented Handle of Console Error Output
end;
关于c - 如何让 Windows Pipe 在进程完成时添加 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57042246/
我是一名优秀的程序员,十分优秀!