我正在尝试为我的游戏制作 DirectX 渲染器。我听说多线程是优化的最佳实践,所以我正在尝试。我有一个基本的渲染器,我正在实现多线程。所以正如标题所说,std::mutex
锁是否适用于被调用的函数?
void DXRenderer::draw(IDirect3DDevice9* _device) {
mutex.lock();
for (const DXCalls::DXCall call : safeCalls) {
switch (call.type) {
case DXCalls::DXCallType::FRECT:
drawFRect(call.FRect);
break;
case DXCalls::DXCallType::RECT:
drawRect(call.Rect);
break;
case DXCalls::DXCallType::LINE:
drawLine(call.Line);
break;
case DXCalls::DXCallType::NONE:
// do literally nothing
break;
default:
MessageBoxA(NULL, "Invalid DXCallType, has a new type not been added to the loop?", "Debug", MB_OK);
break;
}
}
mutex.unlock();
}
举个例子,如果有 2 个线程调用 DXRenderer::draw()
,两个线程会调用 drawFRect
还是会等到互斥锁被解锁?
答案 0 :(得分:1)
举个例子,如果有 2 个线程调用 DXRenderer::draw(),两个线程都会调用 drawFRect
不可以,因为一次只有 1 个线程可以持有互斥锁。
<块引用>要等到互斥锁解锁吗?
是的。这就是互斥锁的全部意义所在。一旦一个线程拥有互斥锁上的锁,任何其他试图获得同一个互斥锁的线程都会等待,直到拥有它的线程解锁它。
仅供参考,您不应该手动调用 lock()
和 unlock()
,而是使用 std::lock_guard
(或类似的 RAII 助手),例如:
void DXRenderer::draw(IDirect3DDevice9* _device) {
std::lock_guard<std::mutex> lock(mutex);
// do work as needed...
} // <-- automatically unlocks here
答案 1 :(得分:0)
调用 draw 函数的第一个线程锁定互斥锁,执行作业,然后解锁互斥锁。如果调用 draw 函数,第二个线程应等待互斥锁被第一个线程解锁。 在给定的时间实例中,只有一个线程可以访问临界区(互斥锁和解锁之间的代码)。这里的函数可以按线程数调用,但任何时候只有一个线程可以访问临界区;剩下的都等着