Mic*_*nda 4 c++ multithreading c++11
每次在Xcode中进行编译时,每次尝试等待condition_variable时都会收到错误消息。错误是“以类型为std :: __ 1 :: system_error的未捕获异常终止:条件变量等待失败:参数无效”
一切在Visual Studio 2013中都可以正常工作。如果我决定不等待多个线程的相同condition_variable,则代码可以正常工作。r
好的,代码。
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;
}
Run Code Online (Sandbox Code Playgroud)
线程池
#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();
};
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
这是真实代码的主要简化,但是足以触发崩溃。
这应该工作吗?我在这里想念什么吗?
您的互斥锁ThreadPool::threadLoop是一个局部变量。这意味着不同的线程锁定在不同的互斥锁上。这是无效的:条件变量绑定到特定的互斥锁,您必须在等待条件之前获取该互斥锁的锁。
你应该在你的类中声明一个_mutex(或者更好的是,使用mutex_命名约定:下划线前缀标识符大多是保留的)成员变量ThreadPool,并始终锁定它。
更准确地说,规范的Requires部分condition_variable::wait()为(N3936§30.5.1[thread.condition.condvar] / p9):
Run Code Online (Sandbox Code Playgroud)void wait(unique_lock<mutex>& lock);要求:
lock.owns_lock()istrue和lock.mutex()被调用线程锁定,或者—没有其他线程在等待该
condition_variable对象,或者-
lock.mutex()返回每个的所有同时等待(通过提供的锁参数相同的值wait,wait_for或wait_until)线程。
因此,每个同时等待a的线程condition_variable必须传递相同的互斥量。从技术上讲,允许两个线程在condition_variable使用一个互斥锁的情况下等待,然后在两个等待都终止(并且没有线程在等待condition_variable)之后,让它们都使用不同的互斥锁在同一对象上等待。我不知道是否有任何实际的用例。
还请注意,std::condition_variable_any::wait()没有这样的要求。对提供的类型的唯一要求是它满足BasicLockable要求,这基本上意味着它具有lock()和unlock()。