技术问询:在主线程锁定std::mutex后于子线程解锁是否合法?
主线程锁定std::mutex后子线程解锁是否合法?
不合法,这属于C++标准定义的未定义行为。
C++标准明确要求:std::mutex的unlock()操作必须由当前持有该互斥锁的线程调用。如果一个线程尝试解锁它没有持有的互斥锁,程序行为完全不可预测——它可能在当前环境下看似正常运行,但这只是巧合,换个编译器、操作系统或者运行场景,就可能触发崩溃、死锁、数据竞争等严重问题。
你提供的代码片段能运行只是未定义行为的一种随机表现,绝对不能依赖这种写法。比如部分平台的互斥锁实现会记录持有锁的线程ID,解锁时会做校验,这种情况下你的代码会直接触发断言失败或程序崩溃。
如果确实需要在子线程中释放锁,应该使用支持所有权转移的锁包装类,比如std::unique_lock,通过std::move把锁的所有权传递给子线程,示例代码如下:
#include <iostream> #include <mutex> #include <thread> int main() { std::mutex mtx; std::unique_lock<std::mutex> lock(mtx); // 将锁的所有权转移到子线程 std::thread([lock = std::move(lock)]() mutable { lock.unlock(); // 子线程此时持有锁,解锁合法 }).join(); std::thread([&](){ mtx.lock(); // 锁已被合法释放,可正常锁定 }).join(); }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

