如何在输入函数之前指定需要哪些互斥锁
How to specify what mutex locks are needed before entering a function
有时编写一个函数,要求在进入该函数之前锁定一个或多个互斥锁。如果未指定此要求,则可以在进入之前调用该函数而无需使用相关锁,这可能会产生灾难性后果。
现在,可以在函数文档中指定这样的东西,但我真的不喜欢这样。
我想在函数的前提条件中指定它(输入函数时断言),但条件应该是什么?
即使 C++11 中的 std::mutex 确实具有 has_lock() 函数,仍然无法保证我是拥有锁的人。
如果您真的不想使用递归互斥锁,并且您的目标是在不尝试获取互斥锁的情况下确定当前线程是否持有互斥锁,那么定义互斥体包装器可能是简单的解决方案。这是一个狂野的镜头:
#include <thread>
#include <mutex>
#include <iostream>
using namespace std;
template<typename M>
struct mutex_wrapper
{
void lock()
{
m.lock();
lock_guard<mutex> l(idGuardMutex);
threadId = this_thread::get_id();
}
void unlock()
{
lock_guard<mutex> l(idGuardMutex);
threadId = thread::id();
m.unlock();
}
bool is_held_by_current_thread() const
{
lock_guard<mutex> l(idGuardMutex);
return (threadId == this_thread::get_id());
}
private:
mutable mutex idGuardMutex;
thread::id threadId;
M m;
};
这是一个如何使用它的简单示例:
int main()
{
cout << boolalpha;
mutex_wrapper<mutex> m;
m.lock();
cout << m.is_held_by_current_thread() << endl;
m.unlock();
cout << m.is_held_by_current_thread() << endl;
}
我认为解决您的困境的答案就是不要使用外部互斥锁。 如果类管理需要同步的资源,则它应使用内部互斥锁并处理所有同步本身。 外部互斥锁很危险,因为它可能会造成死锁和不同步访问。
从评论中,听起来您正在努力解决的问题是重构同步集合。 您希望将一些代码移出类,但必须同步该代码。 下面是如何执行此操作的示例:
class MyCollection {
private:
std::list<Foo> items;
std::mutex lock;
public:
template <class F> void ForEach( F function )
{
std::lock_guard<decltype(this->lock) guard( this->lock );
for( auto item : items )
function( *item );
}
};
这种技术仍有可能出现死锁。 由于函数参数是任意函数,因此它可能会访问集合,从而获取互斥锁。 另一方面,如果"ForEach"应该是只读的,则可能需要此行为。
相关文章:
- 通过 ssh 发送参数.是否有非阻塞输入函数?
- 将int输入函数,将int输入开关,然后更改int的值
- 不能将类中的输入函数与带参数的函数分开
- "cin.get"停止了另一个输入函数,如"cin"..C++
- 模板函数中的错误以获取来自C 输入函数的参数类型
- 两个输入函数的 T(n) 运行时
- 指针在输入函数时丢失值
- (C++)对文件输入函数的递归调用
- 在 Linux 上使用 C 中的输入函数,无需按回车键
- 我在输入函数上做错了什么
- 简单的c++输入函数
- 如何确定未格式化输入函数读取的字符数
- 当我超过第一个 getline() 的输入中的数组大小时,第二个 getline 或其他输入函数不起作用
- 将文件读取到向量中,我的输入函数有什么问题?
- Pthread_create似乎清空了传递给输入函数的参数
- 将具有可变参数的输入函数转换为成员函数
- 直接输入函数
- 如何:捕获输入函数异常的可变包装函数
- 返回命令输入函数
- 是否可以在if语句中使用_getch()或cin或任何输入函数?