C++ 条件变量抛出系统错误与Xcode-罚款与VStudio

C++ 条件变量抛出系统错误与Xcode-罚款与VStudio,c++,multithreading,c++11,C++,Multithreading,C++11,在Xcode中编译时,每次尝试等待条件变量时,我都会遇到一个错误。错误为“以std::\uuu 1::类型的未捕获异常终止:系统错误:条件\u变量等待失败:参数无效” 在Visual Studio 2013中,一切正常。如果我决定不等待来自多个线程的同一个条件变量,代码就会工作。Grrrr 好的,代码 main.cpp: #include "ThreadPool.h" int main(int argc, const char * argv[]) { ThreadPool pool;

在Xcode中编译时,每次尝试等待条件变量时,我都会遇到一个错误。错误为“以std::\uuu 1::类型的未捕获异常终止:系统错误:条件\u变量等待失败:参数无效”

在Visual Studio 2013中,一切正常。如果我决定不等待来自多个线程的同一个条件变量,代码就会工作。Grrrr

好的,代码

main.cpp:

#include "ThreadPool.h"

int main(int argc, const char * argv[])
{
    ThreadPool pool;
    for (int i = 0; i < 10; ++i)
        pool.sendWork();

    std::this_thread::sleep_for(std::chrono::milliseconds(50000));
    return 0;
}
#包括“ThreadPool.h”
int main(int argc,const char*argv[]
{
线程池池;
对于(int i=0;i<10;++i)
pool.sendWork();
std::this_线程::sleep_for(std::chrono::毫秒(50000));
返回0;
}
ThreadPool.h

#pragma once
#include <condition_variable>
#include <vector>
#include <thread>

class ThreadPool
{
protected:
    std::condition_variable     _condition;

private:
    std::vector<std::thread>    _threads;
    void threadLoop();

public:
    ThreadPool();
    void sendWork();
};
#pragma一次
#包括
#包括
#包括
类线程池
{
受保护的:
std::条件\变量\条件;
私人:
std::vector_线程;
void threadLoop();
公众:
线程池();
无效发送工作();
};
ThreadPool.cpp:

#include "ThreadPool.h"

ThreadPool::ThreadPool()
{
    for (unsigned int i {0}; i < 10; ++i)
        _threads.push_back(std::thread(&ThreadPool::threadLoop, this));
}
void ThreadPool::threadLoop()
{
    std::mutex mutex;
    std::unique_lock<std::mutex> lock {mutex};
    _condition.wait(lock);            // This is where the crash happens
}

void ThreadPool::sendWork()
{
    _condition.notify_one();
}
#包括“ThreadPool.h”
线程池::线程池()
{
for(无符号整数i{0};i<10;++i)
_threads.push_back(std::thread(&ThreadPool::threadLoop,this));
}
void ThreadPool::threadLoop()
{
std::互斥互斥;
std::unique_lock{mutex};
_condition.wait(lock);//这就是崩溃发生的地方
}
void ThreadPool::sendWork()
{
_条件。通知_one();
}
这是对真实代码的主要简化,但足以触发崩溃


这样行吗?我在这里遗漏了什么吗?

您在
ThreadPool::threadLoop
中的互斥体是一个局部变量。这意味着不同的线程在不同的互斥锁上锁定。这是无效的:条件变量绑定到特定的互斥体,在等待条件之前,必须获取该互斥体的锁

您应该在
线程池
类中声明一个
\u互斥体
(或者更好地使用
互斥体
命名约定:下划线前缀标识符大部分是保留的)成员变量,并始终锁定该变量。

更准确地说,
条件变量::wait()规范的Requires部分是(N3936§30.5.1[螺纹条件条件条件]/p9):

无效等待(唯一锁定和锁定);
要求:
lock.owners\u lock()
true
lock.mutex()
被 调用线程,以及

-没有其他线程正在等待此
条件变量
对象或

-
lock.mutex()
为all提供的每个锁参数返回相同的值 等待(通过
wait
wait\u for
,或
wait\u to
)线程

因此,同时等待
条件变量
的每个线程必须传递相同的互斥体。技术上允许两个线程使用一个互斥体等待
条件变量
,然后在两个等待结束后(并且没有线程等待
条件变量
),让它们都使用不同的互斥锁等待同一个对象。我不知道是否有任何实际的使用案例


还要注意,
std::condition\u variable\u any::wait()
没有这样的要求。对提供的类型的唯一要求是它满足
BasicLockable
要求,这基本上意味着它有
lock()
unlock()

我在尝试时遇到了不同的问题。如果这是“应该”的工作方式,我会尝试一下,看看会发生什么。ty@MGaz,不要忘记
condition\u变量。wait
可能会错误返回。请确保您也检查了实际情况。
void wait(unique_lock<mutex>& lock);