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

Does a mutex lock apply to functions called after locking?

我正在尝试为我的游戏制作 DirectX 渲染器。我听说 multi-threading 是优化的最佳实践,所以我正在尝试。我有一个基本的渲染器,我正在实施 multi-threading。所以正如标题所说, 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 还是会一直等到互斥体解锁?

As an example, if 2 threads called DXRenderer::draw(), would both threads call drawFRect

不,因为一次只有 1 个线程可以持有互斥锁。

would it wait until the mutex has been unlocked?

是的。这就是互斥量的全部要点。一旦一个线程拥有互斥体上的锁,任何其他试图获得对同一互斥体的锁的线程将等待,直到拥有线程解锁它。

仅供参考,您不应该手动调用 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

调用绘图函数的第一个线程锁定互斥体,执行作业然后解锁互斥体。如果调用绘图函数,第二个线程应等待互斥体被第一个线程解锁。 在给定的时间实例中,只有一个线程可以访问临界区(互斥锁和解锁之间的代码)。这里的函数可以按线程数调用,但是在任何时刻只有一个线程可以访问临界区;休息都得等