You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++11中如何让新线程先于主线程获取std::mutex

如何确保线程t先于main线程获取互斥锁(C++11实现)

你碰到的这个问题确实很常见——直接用std::lock_guard的话,主线程很可能因为线程启动的延迟抢先拿到互斥锁,没法保证线程t先获取。下面我给你两种基于C++11标准的靠谱实现方式:

方案一:使用std::promise和std::future实现同步

这种方式通过线程间的"信号传递"让主线程等待线程t成功锁定互斥锁后,再尝试获取锁。代码示例如下:

#include <mutex>
#include <thread>
#include <future>

std::mutex m;
std::promise<void> t_locked_promise;

void t() {
    std::lock_guard<std::mutex> lock(m);
    // 通知主线程:我已经拿到互斥锁了
    t_locked_promise.set_value();
    
    // 这里可以添加线程t持有锁时需要执行的逻辑
    // ...
}

int main() {
    std::thread t_thread(t);
    
    // 等待线程t发出"已锁定互斥锁"的信号
    t_locked_promise.get_future().wait();
    
    // 此时线程t已经持有锁,主线程再尝试获取(会阻塞直到t释放)
    std::lock_guard<std::mutex> lock(m);
    
    // 主线程持有锁时的逻辑
    // ...
    
    t_thread.join();
    return 0;
}

原理说明

  • 线程t启动后,首先锁定互斥锁,然后通过std::promise::set_value()向主线程的std::future发送信号。
  • 主线程在创建线程后,立即调用future.wait()阻塞,直到收到线程t的信号,才会尝试获取互斥锁。这就完全避免了主线程先抢到锁的可能。

方案二:使用std::condition_variable和标志位

这种方式通过条件变量让主线程等待线程t完成锁的获取,逻辑和promise类似,但更适合需要重复同步的场景:

#include <mutex>
#include <thread>
#include <condition_variable>

std::mutex m;
std::mutex cv_mutex;
std::condition_variable t_locked_cv;
bool t_has_locked = false;

void t() {
    std::lock_guard<std::mutex> lock(m);
    
    // 标记线程t已锁定,并通知主线程
    {
        std::lock_guard<std::mutex> cv_lock(cv_mutex);
        t_has_locked = true;
    }
    t_locked_cv.notify_one();
    
    // 线程t持有锁的逻辑
    // ...
}

int main() {
    std::thread t_thread(t);
    
    // 等待线程t的锁定通知
    {
        std::unique_lock<std::mutex> cv_lock(cv_mutex);
        t_locked_cv.wait(cv_lock, []{ return t_has_locked; });
    }
    
    // 主线程尝试获取锁
    std::lock_guard<std::mutex> lock(m);
    
    // 主线程逻辑
    // ...
    
    t_thread.join();
    return 0;
}

原理说明

  • 线程t锁定互斥锁后,设置标志位t_has_locked并通过条件变量通知主线程。
  • 主线程通过cv.wait()阻塞,直到标志位变为true(确保线程t已经拿到锁),之后才会去尝试获取互斥锁。

注意事项

  • 两种方案的核心都是让主线程等待线程t完成锁的获取动作后,再尝试自己获取锁,从根本上消除了主线程先抢到锁的可能性。
  • 如果你需要线程t持有锁期间执行的逻辑较长,主线程会在尝试获取锁时自然阻塞,直到t释放锁,这符合常规的互斥锁使用逻辑。

内容的提问来源于stack exchange,提问作者Nisba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:09:06