如何 std::mutex::锁定直到函数返回
How to std::mutex::lock until function returns
我想返回一个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();
现在,如果"在这里做超级聪明的事情"是空的怎么办:
// Value.cpp
std::vector<int> GetValue()
{
std::lock_guard<std::mutex> lock(mutex);
return m_value;
}
// MyThread.cpp
auto vec = myVec.GetValue();
那么锁仍然是强制性的吗?为什么?
使用std::lock_guard
通过 RAII 处理锁定和解锁mutex
,这就是它的确切目的。
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
foo
返回后,lg
将超出范围,并在返回时unlock
some_mutex
。
这是打印语句可以真正帮助解决的问题。 例如:
#include <mutex>
#include <iostream>
std::mutex mut;
template <class Mutex>
class Lock
{
Mutex& mut_;
public:
~Lock()
{
std::cout << "unlockn";
mut_.unlock();
}
Lock(const Lock&) = delete;
Lock& operator=(const Lock&) = delete;
Lock(Mutex& mut)
: mut_(mut)
{
mut_.lock();
std::cout << "lockn";
}
};
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 << "Startn";
auto vec = get();
std::cout << "Endn";
}
通过制作我自己的std::lock_guard
版本,我可以插入打印语句来找出互斥锁何时被锁定和解锁。
通过制作一个假std::vector
(上面称为A
(,我可以将打印语句插入到我感兴趣的特殊成员中。 对我来说,这输出:
A() : 0x10fcfb188
Start
lock
A(const A&) : 0x7fff4ff06b28, 0x10fcfb188
unlock
End
~A() : 0x7fff4ff06b28
~A() : 0x10fcfb188
这清楚地表明,在复制0x10fcfb188处的A
时,互斥锁被锁定。
可以通过以下方式更改测试以进行分配:
int
main()
{
A vec;
std::cout << "Startn";
vec = get();
std::cout << "Endn";
}
现在输出:
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
乍一看,分配似乎在锁外进行,因此看起来不安全。 然而,经过仔细检查,人们会看到0x10d8a7190处的受保护A
被复制到锁内的临时A
。 然后解锁互斥锁,并从临时互斥锁到本地进行分配。 没有其他线程可以引用临时线程。 所以只要没有其他线程引用vec
,这又是安全的。
相关文章:
- 从函数返回const char*数组
- 检查函数返回类型是否与STL容器类型值相同
- 从 c 或 cpp 系列子函数返回到主函数
- 从函数返回任意简单类型的数据
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 从 C++ 中的函数返回数组地址问题
- VirtDisk.h QueryChangesVirtualDisk() 函数返回 RangeCount 为 0
- 为什么glGetSubroutineIndex为不同的函数返回相同的值?
- 在 c++ 中将函数返回类型指定为模板参数
- 从封装在对象中的函数 C++ 返回时为空的列表
- 为什么向量内部的指针在从函数返回时会发生变化?
- 函数返回的 rvalue 引用(表达式)是 xvalue - 但没有标识?
- 程序中的布尔函数返回输入的范围无论如何都是无效的
- 寿命延长从函数返回引用
- 程序不向函数返回值
- 字符串函数返回奇怪的值
- 类的大问题,以及从空函数c++返回
- 为什么在尝试测量函数返回所需的时间时,我的运行时编号是错误的?
- C++二叉搜索树模板从函数返回节点
- NVCC 错误:string_view.h:constexpr 函数返回是非常量