Multithreading 在C+中创建一个线程,该线程在调用线程之前获取互斥体+;0x

Multithreading 在C+中创建一个线程,该线程在调用线程之前获取互斥体+;0x,multithreading,c++11,Multithreading,C++11,我有以下情况 std::mutex m; void t() { //lock the mutex m here } main() { //create thread t here //lock the mutex m here } 我希望线程t()在main()之前获取互斥体,我如何使用C++11提供的线程函数来获得这种行为 在main()和t()中简单地放置一个std::lock\u-guard将不起作用,因为它可能需要一段时间才能生成线程,因此可以通过main(

我有以下情况

std::mutex m;

void t() {
    //lock the mutex m here
}

main() {
    //create thread t here
    //lock the mutex m here
}
我希望线程
t()
main()
之前获取互斥体,我如何使用C++11提供的线程函数来获得这种行为


main()
t()
中简单地放置一个
std::lock\u-guard
将不起作用,因为它可能需要一段时间才能生成线程,因此可以通过
main()
锁定互斥锁

std::atomic<bool> threadIsReady{false};

void t()
{
  std::lock_guard<std::mutex> g(m);
  threadIsReady = true;
}

main()
{
  std::thread th(t);
  while (!threadIsReady) {}
  std::lock_guard<std::mutex> g(m);
}
std::原子线程已就绪{false};
void t()
{
标准:锁紧装置g(m);
threadIsReady=true;
}
main()
{
标准:螺纹th(t);
而(!threadIsReady){}
标准:锁紧装置g(m);
}

这里有一个快速而肮脏的方法来实现此效果:

std::atomic<bool> threadIsReady{false};

void t()
{
  std::lock_guard<std::mutex> g(m);
  threadIsReady = true;
}

main()
{
  std::thread th(t);
  while (!threadIsReady) {}
  std::lock_guard<std::mutex> g(m);
}
std::原子线程已就绪{false};
void t()
{
标准:锁紧装置g(m);
threadIsReady=true;
}
main()
{
标准:螺纹th(t);
而(!threadIsReady){}
标准:锁紧装置g(m);
}

关于Sneftel在评论部分提到的条件变量,以及Angew提供的类似解决方案:

一种可能的解决办法:

std::condition_variable cv;
std::mutex m;
bool threadIsReady = false; //bool should be fine in this case

void t() {
    std::unique_lock<std::mutex> g(m);
    threadIsReady = true;
    cv.notify_one();
}


int main() {
    std::thread th(t);

    //if main locks the mutex first, it will have to wait until threadIsReady becomes true
    //if main locks the mutex later, wait will do nothing since threadIsReady would have already been true
    std::unique_lock<std::mutex> g(m);
    cv.wait(g, [] {return threadIsReady; });

}
std::条件变量cv;
std::互斥m;
bool thready=false//在这种情况下布尔应该没问题
void t(){
std::唯一锁g(m);
threadIsReady=true;
cv.通知_one();
}
int main(){
标准:螺纹th(t);
//如果main首先锁定互斥锁,则必须等待threadIsReady变为true
//如果main稍后锁定互斥锁,wait将不起任何作用,因为threadIsReady已经为true
std::唯一锁g(m);
wait(g,[{return threadIsReady;});
}

关于Sneftel在评论部分提到的条件变量,以及Angew提供的类似解决方案:

一种可能的解决办法:

std::condition_variable cv;
std::mutex m;
bool threadIsReady = false; //bool should be fine in this case

void t() {
    std::unique_lock<std::mutex> g(m);
    threadIsReady = true;
    cv.notify_one();
}


int main() {
    std::thread th(t);

    //if main locks the mutex first, it will have to wait until threadIsReady becomes true
    //if main locks the mutex later, wait will do nothing since threadIsReady would have already been true
    std::unique_lock<std::mutex> g(m);
    cv.wait(g, [] {return threadIsReady; });

}
std::条件变量cv;
std::互斥m;
bool thready=false//在这种情况下布尔应该没问题
void t(){
std::唯一锁g(m);
threadIsReady=true;
cv.通知_one();
}
int main(){
标准:螺纹th(t);
//如果main首先锁定互斥锁,则必须等待threadIsReady变为true
//如果main稍后锁定互斥锁,wait将不起任何作用,因为threadIsReady已经为true
std::唯一锁g(m);
wait(g,[{return threadIsReady;});
}

我有点担心您打算将其用作
join
和/或条件变量的替代方案。如果您在这里的目的是等待线程完成,或者直到它完成某些操作,那么这不是合适的方法。不,join与真正的问题无关。不管怎样,从我给你的简单描述来看,你的担心是正确的。只是检查一下。我不确定条件变量,我会考虑一下,我有点担心您打算使用它作为
join
和/或条件变量的替代方案。如果您在这里的目的是等待线程完成,或者直到它完成某些操作,那么这不是合适的方法。不,join与真正的问题无关。不管怎样,从我给你的简单描述来看,你的担心是正确的。只是检查一下。不确定条件变量,我会考虑使用条件变量。在最坏的情况下,让父对象旋转可能会阻止子对象启动。@确实如此;但是,由于我很少编写多线程的程序,我必须查找语法等。我可以从头开始编写原子代码,所以我使用了它。@GemTaylor如果已经有原子值,为什么要使用互斥体?@GemTaylor你指的是另一种情况,还是Angew的代码有问题?因为我看不出它是怎么来的wrong@Nisba“真的”,我指的是条件变量更好。我认为线程实现阻止主线程旋转启动线程是不合法的。最好使用条件变量。在最坏的情况下,让父线程旋转可能会阻止子线程启动。@确实如此;但是,由于我很少编写多线程的程序,我必须查找语法等。我可以从头开始编写原子代码,所以我使用了它。@GemTaylor如果已经有原子值,为什么要使用互斥体?@GemTaylor你指的是另一种情况,还是Angew的代码有问题?因为我看不出它是怎么来的wrong@Nisba“真的”,我指的是条件变量更好。我认为线程实现阻止主线程旋转启动线程是不合法的。