当我在其中什么都不做时,为什么我的 while 循环不起作用(什么都不做循环)?

Why is my while loop not working when I do nothing inside of it (do-nothing loop)?

我只是想使用一个 while 循环来帮助控制我的程序的每秒帧数,该程序显示实时摄像头馈送以及与该摄像头正在查看的内容相对应的数据。这不是微不足道的原因是因为调用 getFramesAfterCapture() 的循环 运行 比相机获取图像快得多(因为它是在收集当前帧和数据的更新方法中调用的两者都需要显示)。

我的想法是让这个函数像使用互斥锁一样简单地等待,直到不再满足我的 while 循环中的条件。回调是另一个线程中的 运行 并且 captureComplete 是 class 的静态成员变量,因此它是它的唯一实例。当从我的相机捕获帧的回调完成捕获新图像时,此 bool 的值会发生变化。必须以这种方式完成,因为我需要显示在屏幕上的数据与帧的捕获同步,这样数据和视频显示匹配。

这是我的代码:

    long CALLBACK FrameGrabber::destCallback(LPVOID lpUser, LPVOID lpReserved) {
        // copy the data into the bitmap
        if (WaitForSingleObject(hMutex, 10) == WAIT_OBJECT_0)
        {
            DWORD dwSize = VIDEO_SIZE;
            //get bitmap
            dpGetSurfaceData(hDest, bitmap + sizeof(BITMAPINFOHEADER), &dwSize);
    
            ReleaseMutex(hMutex);
            // set capture to complete so that waitForCapture releases from the do-nothing loop
            WaitForSingleObject(captureCmpltMutex, INFINITE);
            captureComplete = true;
            ReleaseMutex(captureCmpltMutex);
        }
        
        return 0;
    }
    
    BYTE* FrameGrabber::getFrameAfterCapture() {
        // loop while capture is still not completed
        ////while (!captureComplete);
        while (!captureComplete) { 
            std::cout << "Waiting for capture to complete..." << std::endl;
        }
    
        //std::cout << "Capture Complete!" << std::endl;
        // when capture is completed set captureComplete back to false so that this waits again until the next frame is acquired
        WaitForSingleObject(captureCmpltMutex, INFINITE);
        captureComplete = false;
        ReleaseMutex(captureCmpltMutex);
    
        return bitmap;
    }

我的循环工作正常...

    while (!captureComplete) { 
        std::cout << "Waiting for capture to complete..." << std::endl;
    }

但是当我把它改成这个时不起作用...

    while (!captureComplete);

或者这个...

    while (!captureComplete) { }

或者这个...

    while (!captureComplete) continue;

或者这个...

    while (!captureComplete){ continue; }

我更喜欢任何其他选项,因为我不想在程序完成时在程序中保留打印语句。我希望我的代码在这里看起来像其他似乎不起作用的选项一样漂亮干净。

如果有另一个更优雅的选择,我愿意改变它,我只需要一个有效且看起来干净的解决方案。

我能够找到一个更优雅的解决方案,使用二进制信号量而不是互斥锁或静态成员布尔值。使用互斥量和二进制信号量的区别在于二进制信号量不需要我在 getFrameCapture() 结束时释放信号量。基本上,当一个信号量被释放时,它所持有的计数就会增加 1。相反,当等待函数 returns 时,信号量保持的计数减一。

这允许信号行为,如果我在开始时等待互斥锁并在 getFrameCapture() 方法之前释放它 returns 函数等待帧的整个点被捕获即丢失。同样,如果我不在函数 returned 之前释放它,互斥量将 return WAIT_ABANDONED 告诉程序员线程意外退出并且互斥量已被它放弃。

太阳:

long CALLBACK FrameGrabber::destCallback(LPVOID lpUser, LPVOID lpReserved) {
    // copy the data into the bitmap
    if (WaitForSingleObject(hMutex, 10) == WAIT_OBJECT_0)
    {
        DWORD dwSize = VIDEO_SIZE;
        //get bitmap
        dpGetSurfaceData(hDest, bitmap + sizeof(BITMAPINFOHEADER), &dwSize);

        ReleaseMutex(hMutex);
        //Release semaphore (emit signal)
        ReleaseSemaphore(captureCmpltSemaphore, 1, NULL);
    }
    
    return 0;
}

BYTE* FrameGrabber::getFrameAfterCapture() {
    //Wait for semaphore to be released (Signaled)
    WaitForSingleObject(captureCmpltSemaphore, INFINITE);
    //return bitmap
    return bitmap;
}

我参考了这个 link 来找到我的解决方案: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasesemaphore