CRITICAL_SECTION在使用DuplicateOutput时发生死锁
CRITICAL_SECTION occurs deadlock when using DuplicateOutput
我正在用IDXGIOutputDuplication编写c++/CLI程序。
我想从多个线程获取图像,所以我使用了CriticalSection。但是,包含"AcquireNextFrame()"answers"ReleaseFrame()"的代码,线程被死锁。
如果UpdateDesktopImage()从程序中删除,则不会发生死锁。这些函数调用来自。net框架线程(System.Threading.Thread)。我想知道原因和解决办法。
HRESULT DesktopDupli::Initialize(int dispno, IDXGIAdapter *adapter, IDXGIOutput *output)
{
HRESULT hr = S_OK;
IDXGIOutput1 *dxgi_op1 = NULL;
DXGI_OUTPUT_DESC desc_op;
hr = output->GetDesc(&desc_op);
sw = desc_op.DesktopCoordinates.right - desc_op.DesktopCoordinates.left;
sh = desc_op.DesktopCoordinates.bottom - desc_op.DesktopCoordinates.top;
D3D_FEATURE_LEVEL FeatureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_1
};
D3D_FEATURE_LEVEL level;
UINT levels = ARRAYSIZE(FeatureLevels);
hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN,
NULL, 0, FeatureLevels, levels,
D3D11_SDK_VERSION, &device, &level, &context);
if (FAILED(hr)) goto EXIT;
hr = output->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgi_op1);
if (FAILED(hr)) goto EXIT;
hr = dxgi_op1->DuplicateOutput(device, &dupli);
if (FAILED(hr)) goto EXIT;
this->dispno = dispno;
pixelbufLen = sh * sw * 4;
pixelbuf1 = new BYTE[pixelbufLen];
EXIT:
RELEASE(dxgi_op1);
return hr;
}
void DesktopDupli::Remove()
{
EnterCriticalSection(&csec);
// delete some buffer
if (pixelbuf){
delete[]pixelbuf;
pixelbuf = NULL;
}
LeaveCriticalSection(&csec);
}
HRESULT DesktopDupli::UpdateDesktopImage()
{
EnterCriticalSection(&csec);
HRESULT hr = S_OK;
IDXGIResource* res = NULL;
ID3D11Texture2D *deskimage = NULL;
DWORD c = GetTickCount();
if (c >= lastUpdate && c < lastUpdate + 10) goto EXIT;
lastUpdate = c;
if (!dupli/*<-IDXGIOutputDuplication */) {
hr = E_POINTER;
goto EXIT;
}
dupli->ReleaseFrame();
if (FAILED(hr)) goto EXIT;
hr = dupli->AcquireNextFrame(500, &frameinfo, &res);
if (hr == DXGI_ERROR_WAIT_TIMEOUT) {
hr = S_OK;
goto EXIT;
} else if (FAILED(hr)){
goto EXIT;
}
hr = res->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&deskimage);
if (FAILED(hr)) goto EXIT;
if (frameinfo.AccumulatedFrames == 0) {
dupli->ReleaseFrame();
}else {
hr = SetPixel(deskimage); //CopySubresourceRegion
}
EXIT:
RELEASE(deskimage);
RELEASE(res);
LeaveCriticalSection(&csec);
return hr;
}
in:
hr = res->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&deskimage);
if (FAILED(hr)) goto EXIT;
您忘记在EXIT
之前添加dupli->ReleaseFrame()
相关文章:
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- 用C++中的std::condition_variable将线程置于死锁中会有风险吗
- 使用 std::async 时死锁,将来作为成员
- 如何调试读写器锁的死锁?
- 为什么在Visual Studio 2013上的std::this_thread::sleep_for上死锁
- localtime() 函数正在调用 ___lll_lock_wait_private(),这会使线程陷入死锁
- 如何重现 Boost 进程文档提示的死锁?
- 多线程Windows GUI应用程序中的死锁
- 为什么printf会导致与future.get的死锁,而cout则不会?
- C++中具有阻塞队列和障碍的死锁
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 避免并发等待对象中的死锁
- 在VC++中从DLLMAIN内部调用D3D的CREATEDEVICE时,它会创建一个死锁(loaderlock?)。有没有办法克服这个问题?最终目标内
- 当用2个螺纹锁定时,将recursive_mutex死锁
- 程序在 C++11 中使用条件变量进入死锁
- 一个线程提升的死锁
- 单个生产者/多个消费者死锁
- 当被调用方法使用调用方已锁定的同一锁时,如何避免死锁
- 如何实现无保留和等待以防止死锁