【问题标题】:Finish a thread when condition is produced. C/C++当条件产生时结束一个线程。 C/C++
【发布时间】:2014-09-26 15:52:16
【问题描述】:

我有一个 C 代码来检查鼠标左键是否被按下。它工作正常,但我不知道如何在调用 final() 函数后取消挂钩并退出当前线程。

这是代码:

LRESULT CALLBACK mouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static int count = 0;
static int finalNum;
if (count==0){
    //////Generate random number 
    srand(time(NULL)); // Seed the time
    finalNum = rand() % (150 - 50) + 50; // Generate the number, assign to variable.
    ////////////////////////////////////////////////////////////////////////////
}
//int count = 0;
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
    if (pMouseStruct != NULL){
        if (wParam == WM_LBUTTONDOWN)
        {
            count++;
            printf("%d",count);
            if (count==finalNum){ // user clicked random times the mouse so we launch the final function
                printf("\ndone!\n");
                final();

            }
            printf("clicked");
        }
        printf("Mouse position X = %d  Mouse Position Y = %d\n", pMouseStruct->pt.x, pMouseStruct->pt.y);
    }
    return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

DWORD WINAPI MyMouseLogger(LPVOID lpParm)
{
    HINSTANCE hInstance = GetModuleHandle(NULL);
    // here I put WH_MOUSE instead of WH_MOUSE_LL
    hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, NULL);
    MSG message;

    while (GetMessage(&message, NULL, 0, 0)) {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    UnhookWindowsHookEx(hMouseHook);
    return 0;
}

void custom_delay(){

}

int main(int argc, char *argv[])
{
    int count = 0;
    HANDLE hThread;
    DWORD dwThread;
    //////Generate random number to call a function after rand() number of clicks
    srand(time(NULL)); // Seed the time
    int finalNum = rand() % (150 - 50) + 50; // Generate the number, assign to variable.
    ////////////////////////////////////////////////////////////////////////////

    printf("%d", finalNum);
    hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)MyMouseLogger, (LPVOID)argv[0], NULL, &dwThread);
    if (hThread)
        return WaitForSingleObject(hThread, INFINITE);
    else
        return 1;
    }
printf("Keep going");
}

我已经尝试过 ExitThread(0);但它会关闭所有线程,而不仅仅是 MyMouseLogger 进程以打印“继续”。

我该怎么做?

感谢您的帮助!

【问题讨论】:

  • MyMouseLogger线程退出时,你的main等待它的调用将返回,而main本身将返回......程序终止。你还能期待什么?如果你想看到“继续”,请去掉return之前的WaitForSingleObject(...
  • 您可能缺少一些 WindowsWin32 标签。这看起来不像 C++11 std::thread 或 Posix pthreads。
  • 尝试在final函数中发布一条WM_QUIT消息。
  • [OT]:您只需播种一次,rand 不是线程安全的。您可以改用 C++11 中 <random> 的新功能。

标签: c++ c multithreading winapi


【解决方案1】:

您可以使用 PostThreadMessage 向线程发送 WM_QUIT,这将导致其消息循环退出。

【讨论】:

  • +1 对于这种特定情况,这实际上是一个好主意。有关更通用的方法,请参阅我刚刚发布的答案。
  • 感谢您的回复,但是,我如何将需要用作PostThreadMessage 中的参数的idThread 放入mouseProc 函数中。我这么说是因为 CreateThread 函数在 main 中而不是在 mouseProc 函数中
  • @user1618465 快速的解决方案是将其设置为 static 文件范围变量,然后 mouseProc 可以访问该变量。一个更优雅的解决方案是将所有线程处理放在一个单独的文件中,并将其包装在可以从 main() 调用的函数中。或者,如果 C++ 是一个选项,则为它创建一个类。
【解决方案2】:

这与钩子本身并没有关系;您只是在询问如何安全地停止线程运行。

ExitThread() 从来都不是一个好的选择。所以实现你自己的方式来安全地停止线程。在这种情况下,可以通过例如在创建线程之前通过 CreateEvent() 创建事件来完成。然后让您的线程每次在循环中检查此事件:

while (WaitForSingleObject(hevent_stopthread, 0) != WAIT_OBJECT_0 &&)
       GetMessage(&message, NULL, 0, 0))

hevent_stopthread 它是您自定义事件的句柄。

然后简单地从 final() 函数中设置这个事件。您的 main() 函数将通过返回 0 等待线程自行完成。一旦发生这种情况,您可以通过调用 CloseHandle() 来清理事件。

【讨论】:

  • 你可能想要 MsgWaitForMultipleObjects 在那里,否则当 GetMessage 被阻塞时线程无法退出。
  • 你能告诉我我必须把它放在我的代码中的什么地方吗?我还在学习 C。谢谢
猜你喜欢
  • 1970-01-01
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
  • 2015-02-07
  • 1970-01-01
  • 2011-08-25
相关资源
最近更新 更多