gpt4 book ai didi

c - Win32 匿名管道在首次读取后损坏

转载 作者:行者123 更新时间:2023-11-30 17:19:06 25 4
gpt4 key购买 nike

我正在创建一个进程并通过 win32 api 读取它的标准输出和错误。问题是,在使用 ReadFile() 第一次成功读取后,对于管道中剩余的数据,我总是会在下一个读取时收到损坏的管道错误 (109)。 (所以我只在第一次调用中读取与缓冲区一样大的内容)我怀疑这可能是因为我正在同步读取管道,但在子进程终止之后?

void read_pipes(std::string &output, HANDLE read_pipe) {
assert(read_pipe != nullptr && read_pipe != INVALID_HANDLE_VALUE);
char buffer[4096];
DWORD bytes_left_to_read, err_code; int i = 0;
do {
memset(&buffer, 0, 4096);
err_code = 0;
if (!ReadFile(read_pipe, buffer, 4096 - 1, &bytes_left_to_read, NULL)) {
err_code = GetLastError();
}
assert(err_code != ERROR_IO_PENDING);
if (err_code != 0 && err_code != ERROR_MORE_DATA) {
char sys_err_msg[128];
sys_err_msg[128 - 1] = '\0';
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, err_code, MAKELANGID(0x09, 0x01), sys_err_msg, 127, nullptr);
std::cerr << "Failed to read failed mmdb_importer log, because " << sys_err_msg << ";" << err_code
<< std::endl;
break;
}
output.append(buffer);
} while (true);

以及调用读取的部分代码(完整位于 http://pastebin.com/vakLULyf 下)

if (WaitForSingleObject(mddb_importer_info.hProcess, 60000) == WAIT_TIMEOUT) {
//Kill the importer, probably hangs
TerminateProcess(mddb_importer_info.hProcess, EXIT_FAILURE);
}
GetExitCodeProcess(mddb_importer_info.hProcess, &mddb_importer_return);
//assert (mddb_importer_return != STILL_ACTIVE);

switch (mddb_importer_return) {
case EXIT_SUCCESS:
file_to_upload.uploaded = true;
break;
default:
assert(file_to_upload.uploaded == false);
{
read_pipes(std::ref(file_to_upload.log), mddb_importer_stderr_r);
std::clog << "MDDB_Importer failed with err: : " << file_to_upload.log << std::endl;
read_pipes(std::ref(file_to_upload.log), mddb_importer_stdout_r);
std::clog << "And total size of log " << file_to_upload.log.length() << std::endl;
}
break;
}

最佳答案

是的,看起来我的顺序错误,但由于我不想永远等待一个可能挂起的进程,所以我现在正在通过线程读取管道,我在等待超时之前启动我的 read_pipes 函数, std::异步。以片段为例:

    if (!CloseHandle(mddb_importer_stderr_w)) throw std::runtime_error("Can not create mddb_importer pipes");


auto err = std::async(std::launch::async, read_pipes, mddb_importer_stderr_r);
auto out = std::async(std::launch::async, read_pipes, mddb_importer_stdout_r);

if (WaitForSingleObject(mddb_importer_info.hProcess, 60000) == WAIT_TIMEOUT) {
//Kill the importer, probably hangs
TerminateProcess(mddb_importer_info.hProcess, EXIT_FAILURE);
}
GetExitCodeProcess(mddb_importer_info.hProcess, &mddb_importer_return);
//assert (mddb_importer_return != STILL_ACTIVE);

const std::string err_string = err.get();

关于c - Win32 匿名管道在首次读取后损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28962036/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com