c++ 如何用WINAPI函数修复无限循环?

yacmzcpb  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(141)

我尝试编写一个超时函数,如果用户在给定的时间内没有选择任何选项,就会将其踢出,但是我发现自己陷入了一个无限循环,甚至我的等待计时器也无法破坏这个循环。
我的代码:

namespace jsw {
    namespace threading {
        class auto_event {
        public:
            auto_event() : _event(CreateEvent(0, false, false, 0)) {}

            BOOL wait(DWORD timeout = 1) const
            {
                return WaitForSingleObject(_event, timeout) == WAIT_OBJECT_0;
            }

            BOOL set() { return SetEvent(_event); }
            BOOL reset_event() { return ResetEvent(_event); }
        private:
            HANDLE _event;
        };

        class thread {
        public:
            static thread start(
                LPTHREAD_START_ROUTINE fn, LPVOID args = 0,
                DWORD state = 0, DWORD timeout = 5000)
            {
                return thread(CreateThread(0, 0, fn, args, state, 0), timeout);
            }

            static void sleep(DWORD milliseconds) { Sleep(milliseconds); }
            static void exit(DWORD exitCode) { ExitThread(exitCode); }
        public:
            thread(HANDLE thread, DWORD timeout) : _thread(thread), _timeout(timeout) {}
            ~thread() { CloseHandle(_thread); }

            DWORD exit_code() const
            {
                DWORD exitCode = NO_ERROR;

                GetExitCodeThread(_thread, &exitCode);

                return exitCode;
            }

            HANDLE handle() const { return _thread; }
            BOOL is_alive() const { return exit_code() == STILL_ACTIVE; }
            DWORD join() { return WaitForSingleObject(_thread, _timeout); }
            DWORD suspend() { return SuspendThread(_thread); }
            DWORD resume() { return ResumeThread(_thread); }
            BOOL abort(DWORD exitCode) { return TerminateThread(_thread, exitCode); }
        private:
            HANDLE _thread;
            DWORD _timeout;
        };
    }
}

DWORD WINAPI get_option(LPVOID args)
{
    using namespace jsw::threading;

    int* option = (int*)((LPVOID*)args)[0];
    auto_event* e = (auto_event*)((LPVOID*)args)[1];

    std::cin >> *option;
    e->set();

    return NO_ERROR;
}

int main()
{
    using namespace jsw::threading;

    int option{};
    auto_event e;
    LPVOID args[2] = { &option, &e };

    thread worker = thread::start(get_option, args);

    if (e.wait(5000)) {
        do {
            system("cls");

            switch (option) {
            case 1: // Do some stuff...
                break;
            case 2: // Do some stuff...
                break;
            case 3: // Exit
                break;
            default: std::cout << "Option not valid!" << std::endl;
                break;
            }
        } while (option != 3);
        std::cout << "***Program Exit***" << std::endl;
    }
    else {
        worker.abort(NO_ERROR);
        std::cout << "***PROGRAM END***\n";
    }
}

我设法使循环在get_option函数中工作;然而我遇到了一个超时函数的问题,因为它不能在里面工作,所以我决定把循环放在主函数里,但是什么也不能用。
如果可能的话,谁能告诉我如何修复这个无限循环和计时器?

ggazkfy8

ggazkfy81#

就像“某个程序员说的,
线程函数get_option没有循环。在第一次输入后,它将退出,不再运行。
你可以把**输入法(get_option)**放在一个循环中,这里我使用while作为参考。

int main()
{
    using namespace jsw::threading;

    int option{};
    auto_event e;
    LPVOID args[2] = { &option, &e };

    while (true)
    {
        thread worker = thread::start(get_option, args);

        if (e.wait(5000)) {
            //do {
                //system("cls");

                switch (option) {
                case 1:
                    std::cout << "Option 1" << std::endl;
                    break;
                case 2:
                    std::cout << "Option 2" << std::endl;
                    break;
                case 3: // Exit
                    break;
                default: std::cout << "Option not valid!" << std::endl;
                    break;
                }
            //} while (option != 3);
            //std::cout << "***Program Exit***" << std::endl;
            //break;
        }
        else {
            worker.abort(NO_ERROR);
            std::cout << "***PROGRAM END***\n";
            break;
        }
    }

}

相关问题