在Windows上等待进程随机失败
Waiting on a process on Windows randomly fails
我有一个项目是编译器。我的编译器有一个集成测试套件,它将样本源编译成一个对象,调用ld链接它,然后调用可执行文件并检查结果。这三个步骤中的每一个都是独立于测试驱动程序的全新过程。
不幸的是,我看到了随机测试失败,因为出于某种原因,当我进入链接时,上一个测试还没有完成运行,尽管我明确地等待每个进程的终止,然后再开始下一步。因此ld失败,因为它无法写出新的可执行文件。
我可以通过在新目录中运行每个测试或为临时文件提供唯一的名称来解决这个问题,但我不想这样做,因为这种方法应该有效,我只是在掩盖我不能等待进程正确终止的问题。
这是我启动和等待流程的代码:
#include <Windows.h>
#include <iostream>
#include <thread>
class Pipe {
HANDLE ReadHandle;
HANDLE writehandle;
public:
Pipe() {
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
CreatePipe(&ReadHandle, &writehandle, &saAttr, 0);
}
HANDLE WriteHandle() {
return writehandle;
}
std::string Contents() {
CloseHandle(writehandle);
DWORD dwRead;
CHAR chBuf[1024];
BOOL bSuccess = FALSE;
std::string result;
for (;;)
{
bSuccess = ReadFile(ReadHandle, chBuf, 1024, &dwRead, NULL);
if (!bSuccess || dwRead == 0) break;
result += std::string(chBuf, chBuf + dwRead);
}
return result;
}
~Pipe() {
CloseHandle(ReadHandle);
}
};
Wide::Driver::ProcessResult Wide::Driver::StartAndWaitForProcess(std::string name, std::vector<std::string> args, Util::optional<unsigned> timeout)
{
auto throw_last_err = [] {
DWORD dw = GetLastError();
const char* message;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&message, 0, nullptr);
std::string err = message;
LocalFree((void*)message);
throw std::runtime_error(err);
};
ProcessResult result;
Pipe stdoutpipe;
Pipe stderrpipe;
PROCESS_INFORMATION info = { 0 };
STARTUPINFO startinfo = { sizeof(STARTUPINFO) };
std::string final_args = name;
for (auto arg : args)
final_args += " " + arg;
startinfo.hStdOutput = stdoutpipe.WriteHandle();
startinfo.hStdError = stderrpipe.WriteHandle();
startinfo.hStdInput = INVALID_HANDLE_VALUE;
startinfo.dwFlags |= STARTF_USESTDHANDLES;
auto proc = CreateProcess(
name.c_str(),
&final_args[0],
nullptr,
nullptr,
TRUE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
nullptr,
nullptr,
&startinfo,
&info
);
if (!proc) {
throw_last_err();
}
if (timeout == 0)
timeout = INFINITE;
std::thread writethread([&] {
result.std_out = stdoutpipe.Contents();
});
std::thread errthread([&] {
result.std_err = stderrpipe.Contents();
});
auto waiterr = WaitForSingleObject(info.hProcess, timeout ? *timeout : INFINITE);
if (waiterr == WAIT_TIMEOUT) {
TerminateProcess(info.hProcess, 1);
waiterr = WaitForSingleObject(info.hProcess, timeout ? *timeout : INFINITE);
if (waiterr != WAIT_OBJECT_0) {
throw_last_err();
}
} else if (waiterr != WAIT_OBJECT_0) {
throw_last_err();
}
writethread.join();
errthread.join();
DWORD exit_code;
GetExitCodeProcess(info.hProcess, &exit_code);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
result.exitcode = exit_code;
if (exit_code != 0)
return result;
return result;
}
throw_last_err()
从未被调用,所以一切都很顺利。
为什么我不能等待流程?
根据评论,像Search这样的各种Windows组件可以锁定随机文件。这对我来说意味着,一般来说,我不能假设文件不会被锁定,因此我不应该假设我可以立即重用它。
因此,我决定不再重复使用中间文件。
相关文章:
- 如果没有malloc,链表实现将失败
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- 为什么 Serial.println(<char[]>);返回随机字符?
- 字符串-C++后显示的随机字符
- 视图中的参数推导失败:take_while
- 链接到自行创建的dll失败
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- OpenSSL RSA 解密随机失败 C/C++
- 测试随机失败
- 如何创建随机内存分配失败
- 似乎是随机程序在完成C++时失败
- 使用快速英特尔随机生成器(SSE2)会因堆栈问题而失败..已损坏
- 在Windows上等待进程随机失败
- 从管道读取随机失败
- RSA_Private_Decrypt随机失败
- 在CentOS 6.4上使用Boost.Regex 1.53和gcc 4.8.1随机断言失败
- 随机运行失败与简单的计数项目