mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 02:55:38 +08:00
perf.优化读取管道的CPU占用
This commit is contained in:
@@ -169,8 +169,10 @@ namespace asst
|
||||
|
||||
inline std::string callcmd(const std::string& cmdline)
|
||||
{
|
||||
constexpr int BuffSize = 4096;
|
||||
constexpr int PipeBuffSize = 4096;
|
||||
std::string pipe_str;
|
||||
auto pipe_buffer = std::make_unique<char[]>(PipeBuffSize);
|
||||
|
||||
#ifdef _WIN32
|
||||
SECURITY_ATTRIBUTES pipe_sec_attr = { 0 };
|
||||
pipe_sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
@@ -178,7 +180,7 @@ namespace asst
|
||||
pipe_sec_attr.bInheritHandle = TRUE;
|
||||
HANDLE pipe_read = nullptr;
|
||||
HANDLE pipe_child_write = nullptr;
|
||||
CreatePipe(&pipe_read, &pipe_child_write, &pipe_sec_attr, BuffSize);
|
||||
CreatePipe(&pipe_read, &pipe_child_write, &pipe_sec_attr, PipeBuffSize);
|
||||
|
||||
STARTUPINFOA si = { 0 };
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
@@ -191,18 +193,12 @@ namespace asst
|
||||
|
||||
BOOL p_ret = CreateProcessA(nullptr, const_cast<LPSTR>(cmdline.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi);
|
||||
if (p_ret) {
|
||||
DWORD peek_num = 0;
|
||||
DWORD read_num = 0;
|
||||
DWORD std_num = 0;
|
||||
do {
|
||||
while (::PeekNamedPipe(pipe_read, nullptr, 0, nullptr, &read_num, nullptr) && read_num > 0) {
|
||||
char* pipe_buffer = new char[read_num];
|
||||
BOOL read_ret = ::ReadFile(pipe_read, pipe_buffer, read_num, &std_num, nullptr);
|
||||
if (read_ret) {
|
||||
pipe_str.append(pipe_buffer, pipe_buffer + std_num);
|
||||
}
|
||||
if (pipe_buffer != nullptr) {
|
||||
delete[] pipe_buffer;
|
||||
pipe_buffer = nullptr;
|
||||
while (::PeekNamedPipe(pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) {
|
||||
if (::ReadFile(pipe_read, pipe_buffer.get(), peek_num, &read_num, nullptr)) {
|
||||
pipe_str.append(pipe_buffer.get(), pipe_buffer.get() + read_num);
|
||||
}
|
||||
}
|
||||
} while (::WaitForSingleObject(pi.hProcess, 0) == WAIT_TIMEOUT);
|
||||
@@ -248,14 +244,12 @@ namespace asst
|
||||
close(pipe_in[PIPE_READ]);
|
||||
close(pipe_out[PIPE_WRITE]);
|
||||
|
||||
std::unique_ptr<char> pipe_buffer(new char[BuffSize + 1]);
|
||||
do {
|
||||
memset(pipe_buffer.get(), 0, BuffSize);
|
||||
ssize_t read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), BuffSize);
|
||||
ssize_t read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize);
|
||||
|
||||
while (read_num > 0) {
|
||||
pipe_str.append(pipe_buffer.get(), pipe_buffer.get() + read_num);
|
||||
read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), BuffSize);
|
||||
read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize);
|
||||
};
|
||||
} while (::waitpid(child, nullptr, WNOHANG) == 0);
|
||||
|
||||
@@ -268,10 +262,10 @@ namespace asst
|
||||
close(pipe_in[PIPE_WRITE]);
|
||||
close(pipe_out[PIPE_READ]);
|
||||
close(pipe_out[PIPE_WRITE]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return pipe_str;
|
||||
}
|
||||
}
|
||||
|
||||
//template<typename T,
|
||||
// typename = typename std::enable_if<std::is_constructible<T, std::string>::value>::type>
|
||||
@@ -313,5 +307,5 @@ namespace asst
|
||||
// }
|
||||
// return str;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,26 +397,20 @@ std::pair<bool, std::vector<unsigned char>> asst::Controller::call_command(const
|
||||
std::unique_lock<std::mutex> pipe_lock(pipe_mutex);
|
||||
|
||||
std::vector<uchar> pipe_data;
|
||||
auto pipe_buffer = std::make_unique<uchar[]>(PipeBuffSize);
|
||||
|
||||
#ifdef _WIN32
|
||||
PROCESS_INFORMATION process_info = { 0 }; // 进程信息结构体
|
||||
::CreateProcessA(nullptr, const_cast<LPSTR>(cmd.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &m_child_startup_info, &process_info);
|
||||
|
||||
DWORD peek_num = 0;
|
||||
DWORD read_num = 0;
|
||||
do {
|
||||
//DWORD write_num = 0;
|
||||
//WriteFile(parent_write, cmd.c_str(), cmd.size(), &write_num, nullptr);
|
||||
|
||||
DWORD read_num = 0;
|
||||
DWORD std_num = 0;
|
||||
while (::PeekNamedPipe(m_pipe_read, nullptr, 0, nullptr, &read_num, nullptr) && read_num > 0) {
|
||||
uchar* pipe_buffer = new uchar[read_num];
|
||||
BOOL read_ret = ::ReadFile(m_pipe_read, pipe_buffer, read_num, &std_num, nullptr);
|
||||
if (read_ret) {
|
||||
pipe_data.insert(pipe_data.end(), pipe_buffer, pipe_buffer + std_num);
|
||||
}
|
||||
if (pipe_buffer != nullptr) {
|
||||
delete[] pipe_buffer;
|
||||
pipe_buffer = nullptr;
|
||||
while (::PeekNamedPipe(m_pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) {
|
||||
if (::ReadFile(m_pipe_read, pipe_buffer.get(), PipeBuffSize, &read_num, nullptr)) {
|
||||
pipe_data.insert(pipe_data.end(), pipe_buffer.get(), pipe_buffer.get() + read_num);
|
||||
}
|
||||
}
|
||||
} while (::WaitForSingleObject(process_info.hProcess, 0) == WAIT_TIMEOUT);
|
||||
@@ -451,10 +445,7 @@ std::pair<bool, std::vector<unsigned char>> asst::Controller::call_command(const
|
||||
else if (m_child > 0) {
|
||||
// parent process
|
||||
// LogTraceScope("Parent process: " + cmd);
|
||||
constexpr int BuffSize = 4096;
|
||||
std::unique_ptr<uchar> pipe_buffer(new uchar[BuffSize + 1]);
|
||||
do {
|
||||
memset(pipe_buffer.get(), 0, BuffSize);
|
||||
ssize_t read_num = read(m_pipe_out[PIPE_READ], pipe_buffer.get(), BuffSize);
|
||||
|
||||
while (read_num > 0) {
|
||||
@@ -562,6 +553,7 @@ int asst::Controller::push_cmd(const std::string & cmd)
|
||||
void asst::Controller::wait(unsigned id) const noexcept
|
||||
{
|
||||
while (id > m_completed_id) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace asst
|
||||
cv::Mat m_cache_image;
|
||||
bool m_image_convert_lf = false;
|
||||
|
||||
constexpr static int PipeBuffSize = 1048576; // 管道缓冲区大小
|
||||
constexpr static int PipeBuffSize = 4 * 1024; // 管道缓冲区大小
|
||||
#ifdef _WIN32
|
||||
HANDLE m_pipe_read = nullptr; // 读管道句柄
|
||||
HANDLE m_pipe_write = nullptr; // 写管道句柄
|
||||
|
||||
@@ -183,6 +183,7 @@
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<Profile>true</Profile>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
@@ -228,6 +229,7 @@ xcopy /e /y /i /c $(SolutionDir)3rdparty\resource $(TargetDir)resource</Command>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<Profile>true</Profile>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
namespace asst
|
||||
{
|
||||
constexpr static const char* Version = "v2.6.0";
|
||||
constexpr static const char* Version = "v2.6.1";
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>MeoAssistant.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<Profile>true</Profile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||
@@ -101,6 +102,7 @@
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>MeoAssistant.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<Profile>true</Profile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
Reference in New Issue
Block a user