我有一个主线程,它有一个控制台窗口。我使用std::atexit()来注册atexit_handler()。然后我使用SetConsoleCtrlHandler注册一个函数,该函数的全部目的是检查传递的DWORD是否等于CTRL_CLOSE_EVENT,如果是,则调用atexit_handler()。main函数有一个while循环,检查global::exit是否为true(global::exit是main. h中命名空间内的布尔值)。当while循环中断时,下一步是调用atexit_handler(),然后返回0。
问题是还有一个单独的线程,让我们称之为monitorThread,它可以在任何时候声明是时候关闭了,但是如果我通过设置global::exit为true来这样做,那么这是一个多线程(不只是这两个),必须与该共享变量交互。另一方面,我可以让monitorThread调用atexit_handler(),并让atexit_handler()在join()调用其他线程之前将exit设置为true,但是main最终会再次调用atexit_handler()。
所以,我的总体问题是,既然没有数据需要刷新到磁盘,我真的需要退出处理函数来释放内存和加入线程吗?或者我可以简单地让monitorThread调用exit(),让操作系统从轨道上清除一切?
如果我可以简单地让操作系统处理它,那么通过让我完全摆脱退出bool来简化事情。
以下是我目前拥有的:
GamewindowAndInput.h:
#pragma once
#include <Windows.h>
namespace GWAI {
HWND getHWND();
void inputLoop();
void forkWaiter();
}
GamewindowAndInput.cpp:
#pragma once
#include "GamewindowAndInput.h"
#include <iostream>
#include "main.h"
HWND GWAI::getHWND() {
HWND hwnd = FindWindow(NULL, L"[redacted]");
if (hwnd == NULL) {
"Game window not found, launching";
//system("start [redacted]");
//instead, fork exec ^, spawn new thread to wait on pid before setting exit to true
Sleep(5000);
hwnd = FindWindow(NULL, L"[redacted]");
}
while (hwnd == NULL) {
std::cout << "Game window not found" << std::endl;
Sleep(100);
hwnd = FindWindow(NULL, L"[redacted]");
}
std::cout << "Valid HWND" << std::endl;
return hwnd;
}
void GWAI::forkWaiter() {
}
void GWAI::inputLoop() {
while (true) {
//migrate from main.cpp
}
}
main.h:
#pragma once
#include <Windows.h>
int main(int argc, char* argv[]);
namespace global {
bool run = false, exit = false; //replace with atomic bool?
HWND hwnd;
}
BOOL WINAPI cntrlHandler(DWORD type);
void atexit_handler();
main.cpp:
#pragma once
#include <Windows.h>
#include <iostream>
#include <cstdlib>
#include "main.h"
#include "GamewindowAndInput.h"
using std::cout; using std::endl;
constexpr int EVERY_NTH = 2;
int main(int argc, char* argv[]) {
std::atexit(atexit_handler);
SetConsoleCtrlHandler(cntrlHandler, TRUE);
//create thread of &inputLoop
global::hwnd = GWAI::getHWND();
long i = 0;
while (!global::exit) {
if (global::hwnd != GetForegroundWindow()) {
global::run = false;
Sleep(10);
continue;
}
if (GetKeyState(VK_NUMPAD3) & 0x8000/*Check if high-order bit is set (1 << 15)*/) {
global::run = true;
Sleep(500);
}
if (global::run) {
while (global::hwnd == GetForegroundWindow()) {
if (GetKeyState(VK_NUMPAD3) & 0x8000/*Check if high-order bit is set (1 << 15)*/) {
global::run = false;
Sleep(500);
break;
}
//insert actual main function here
if (global::exit)
goto begone;
}
}
}
begone:
atexit_handler();
return 0;
}
void atexit_handler(){
//join threads
}
BOOL WINAPI cntrlHandler(DWORD type) {
if (type == CTRL_CLOSE_EVENT) {
atexit_handler();
return TRUE;
}
return FALSE;
}
1条答案
按热度按时间lhcgjxsq1#
当使用线程时,良好的关闭与良好的启动和同步一样重要,以避免数据中断。
下面是我用代码写的一个例子。在线演示此处https://onlinegdb.com/6IkjrQWZN: