为什么当我在while循环中什么都不做时(什么也不做循环),它就不工作了



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

我的想法是让这个函数像使用互斥锁一样简单地等待,直到while循环中的条件不再满足。回调正在另一个线程中运行,captureComplete是该类的静态成员变量,因此它是它的唯一实例。当从我的相机捕获帧的回调完成捕获新图像时,此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((结束时释放信号量。基本上,当信号量被释放时,它所保持的计数会增加一。相反,当等待函数返回时,信号量保持的计数会减少一。

这允许了信号行为,如果我在一开始就等待互斥,并在getFrameCapture((方法返回等待捕获帧的函数的整个点之前释放它,那么就会丢失。同样,如果我不在函数返回之前释放它,互斥体将返回WAIT_ABANDONED,告诉程序员线程意外退出,互斥体已被它放弃。

Sol:

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;
}

我引用了此链接以查找我的解决方案:https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-releasesemaphore

最新更新