Kor*_*idu 10 c++ concurrency thread-safety
我想回来一个std::vector.这std::vector可以从其他线程(读和写)访问.std::mutex功能完成返回后如何解锁我的刚才?
例如,在:
// Value.cpp
std::vector<int> GetValue()
{
std::lock_guard<std::mutex> lock(mutex);
// Do super smart stuff here
// ...
return m_value;
}
// MyThread.cpp
auto vec = myVec.GetValue();
Run Code Online (Sandbox Code Playgroud)
现在如果"在这里做超级聪明的东西"是空的:
// Value.cpp
std::vector<int> GetValue()
{
std::lock_guard<std::mutex> lock(mutex);
return m_value;
}
// MyThread.cpp
auto vec = myVec.GetValue();
Run Code Online (Sandbox Code Playgroud)
锁是否仍然是强制性的?为什么?
Cor*_*mer 19
使用a std::lock_guard来处理锁定和解锁mutexvia RAII,这就是它的用途.
int foo()
{
std::lock_guard<std::mutex> lg(some_mutex); // This now locked your mutex
for (auto& element : some_vector)
{
// do vector stuff
}
return 5;
} // lg falls out of scope, some_mutex gets unlocked
Run Code Online (Sandbox Code Playgroud)
之后foo的回报,lg就会掉出来的范围,unlock some_mutex当它.
这是印刷语句可以真正帮助的那种问题.例如:
#include <mutex>
#include <iostream>
std::mutex mut;
template <class Mutex>
class Lock
{
Mutex& mut_;
public:
~Lock()
{
std::cout << "unlock\n";
mut_.unlock();
}
Lock(const Lock&) = delete;
Lock& operator=(const Lock&) = delete;
Lock(Mutex& mut)
: mut_(mut)
{
mut_.lock();
std::cout << "lock\n";
}
};
struct A
{
~A()
{
std::cout << "~A() : " << this << "\n";
}
A()
{
std::cout << "A() : " << this << "\n";
}
A(const A& a)
{
std::cout << "A(const A&) : " << this << ", " << &a << "\n";
}
A& operator=(const A& a)
{
std::cout << "A& operator=(const A&) : " << this << ", " << &a << "\n";
return *this;
}
};
A a;
A
get()
{
Lock<std::mutex> lk(mut);
return a;
}
int
main()
{
std::cout << "Start\n";
auto vec = get();
std::cout << "End\n";
}
Run Code Online (Sandbox Code Playgroud)
通过制作我自己的版本std::lock_guard,我可以插入print语句来找出互斥锁被锁定和解锁的时间.
并且,通过假的std::vector(称为A以上),我可以插入打印语句插入特殊的成员,我很感兴趣,对我来说,这个输出:
A() : 0x10fcfb188
Start
lock
A(const A&) : 0x7fff4ff06b28, 0x10fcfb188
unlock
End
~A() : 0x7fff4ff06b28
~A() : 0x10fcfb188
Run Code Online (Sandbox Code Playgroud)
这清楚地表明A在复制at 0x10fcfb188 时,互斥锁被锁定.
可以更改测试以进行分配:
int
main()
{
A vec;
std::cout << "Start\n";
vec = get();
std::cout << "End\n";
}
Run Code Online (Sandbox Code Playgroud)
现在输出:
A() : 0x10d8a7190
A() : 0x7fff5235ab28
Start
lock
A(const A&) : 0x7fff5235ab18, 0x10d8a7190
unlock
A& operator=(const A&) : 0x7fff5235ab28, 0x7fff5235ab18
~A() : 0x7fff5235ab18
End
~A() : 0x7fff5235ab28
~A() : 0x10d8a7190
Run Code Online (Sandbox Code Playgroud)
起初,看起来分配发生在锁外,因此看起来不安全.然而,仔细观察后,人们会看到受保护A的0x10d8a7190被复制到A锁内部的临时位置.然后解锁互斥锁,并从临时到本地进行分配.没有其他线程可能引用临时.因此,只要没有其他线程引用vec,这又是安全的.
| 归档时间: |
|
| 查看次数: |
5122 次 |
| 最近记录: |