互斥锁是否适用于锁定后调用的函数?

时间:2021-02-11 19:55:42

标签: c++ multithreading directx mutex

我正在尝试为我的游戏制作 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 还是会等到互斥锁被解锁?

2 个答案:

答案 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 函数,第二个线程应等待互斥锁被第一个线程解锁。 在给定的时间实例中,只有一个线程可以访问临界区(互斥锁和解锁之间的代码)。这里的函数可以按线程数调用,但任何时候只有一个线程可以访问临界区;剩下的都等着