unique_lock across threads?
unique_lock across threads?
我在概念化unique_lock
应该如何跨线程运行时遇到了一些麻烦。我试图做一个简单的例子来重新创建我通常会使用condition_variable
的东西。
#include <mutex>
#include <thread>
using namespace std;
mutex m;
unique_lock<mutex>* mLock;
void funcA()
{
//thread 2
mLock->lock();//blocks until unlock?Access violation reading location 0x0000000000000000.
}
int _tmain(int argc, _TCHAR* argv[])
{
//thread 1
mLock = new unique_lock<mutex>(m);
mLock->release();//Allows .lock() to be taken by a different thread?
auto a = std::thread(funcA);
std::chrono::milliseconds dura(1000);//make sure thread is running
std::this_thread::sleep_for(dura);
mLock->unlock();//Unlocks thread 2's lock?
a.join();
return 0;
}
同时从多个线程访问unique_lock
。 它不是以这种方式设计为线程安全的。 相反,多个unique_lock
(局部变量)引用相同的全局mutex
。 只有mutex
本身被设计为可由多个线程同时访问。 即便如此,我的陈述也不~mutex()
.
例如,人们知道mutex::lock()
可以被多个线程访问,因为它的规范包括以下内容:
同步:对同一对象的先前
unlock()
操作应与 (4.7) 此操作同步。
其中同步是 4.7 [intro.multithread] (及其子句)中定义的技术术语。
这看起来不太对劲。首先,release
是"解除互斥锁而不解锁互斥锁",这不太可能是你想在那个地方做的事情。这基本上意味着您的unique_lock<mutex>
中不再有mutex
- 这将使它变得毫无用处 - 并且可能是您获得"访问违规"的原因。
编辑:在对您的代码进行一些"按摩"并说服g ++ 4.6.3做我想做的事情(因此#define _GLIBCXX_USE_NANOSLEEP
),这是一个工作示例:
#define _GLIBCXX_USE_NANOSLEEP
#include <chrono>
#include <mutex>
#include <thread>
#include <iostream>
using namespace std;
mutex m;
void funcA()
{
cout << "FuncA Before lock" << endl;
unique_lock<mutex> mLock(m);
//thread 2
cout << "FuncA After lock" << endl;
std::chrono::milliseconds dura(500);//make sure thread is running
std::this_thread::sleep_for(dura); //this_thread::sleep_for(dura);
cout << "FuncA After sleep" << endl;
}
int main(int argc, char* argv[])
{
cout << "Main before lock" << endl;
unique_lock<mutex> mLock(m);
auto a = std::thread(funcA);
std::chrono::milliseconds dura(1000);//make sure thread is running
std::this_thread::sleep_for(dura); //this_thread::sleep_for(dura);
mLock.unlock();//Unlocks thread 2's lock?
cout << "Main After unlock" << endl;
a.join();
cout << "Main after a.join" << endl;
return 0;
}
不知道为什么需要使用new
来创建锁。当然,unique_lock<mutex> mlock(m);
应该这样做(当然,将mLock->
相应地更改为mLock.
)。
锁只是一个自动防护装置,它以安全和理智的方式操作互斥锁。
你真正想要的是这段代码:
std::mutex m;
void f()
{
std::lock_guard<std::mutex> lock(m);
// ...
}
这有效地"同步"了对f
的调用,因为进入它的每个线程都会阻塞,直到它设法获得互斥锁。
unique_lock
只是lock_guard
的增强版本:它可以构建为解锁,移动(谢谢,@MikeVine),它本身是一个"可锁定的对象",就像互斥锁本身一样,因此它可以用于例如在可变参数std::lock(...)
中以无死锁的方式一次锁定多个事物,并且可以由std::condition_variable
管理(谢谢, @syam)。
但除非你有充分的理由使用unique_lock
,否则更喜欢使用lock_guard
。一旦你需要升级到一个 unique_lock
,你就会知道为什么。
作为旁注,上面的答案跳过了互斥锁的即时锁定和延迟锁定之间的区别:
#include<mutex>
::std::mutex(mu);
auto MyFunction()->void
{
std::unique_lock<mutex> lock(mu); //Created instance and immediately locked the mutex
//Do stuff....
}
auto MyOtherFunction()->void
{
std::unique_lock<mutex> lock(mu,std::defer_lock); //Create but not locked the mutex
lock.lock(); //Lock mutex
//Do stuff....
lock.unlock(); //Unlock mutex
}
MyFunction() 显示广泛使用的即时锁,而 MyOtherFunction() 显示延迟锁。
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- C++ Win32 Threads
- Threads with Classes and std::packaged_task
- 包含 std::threads 的元素向量
- 为什么 C++ 中的 THREADS 在执行时给出不同的输出?
- 我无法创建 Poco::Threads 的向量
- 如何在 <threads> c++ 中使用和一维数组进行矩阵乘法?
- Threads within C++ class
- 如何中断其他 std::threads c++
- 是否可以使用 boost::threads 中的 std::this_thread* 函数
- Flask, boost::python and threads
- htop and OpenMP threads
- Python GIL and threads
- ZeroMQ - Number of Threads
- C++ & boost::threads - 如何根据工作类型确定线程的优先级?
- c++ winapi threads
- std::threads 构造函数参数错误
- 如何在许多处理器上运行 boost::threads
- unique_lock across threads?
- 从boost::threads到boost::asio定时器