- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在这里读这个旧的Boost Thread FAQ其中有为具有 boost::mutex
不可复制对象作为成员的类实现复制构造和赋值运算符的指南。
我对复制构造函数没意见,但我对赋值运算符有些怀疑。下面的指令还有效吗?
// old boost thread
const counter & operator=( const counter& other ){
if (this == &other)
return *this;
boost::mutex::scoped_lock lock1(&m_mutex < &other.m_mutex ?
m_mutex : other.m_mutex);
boost::mutex::scoped_lock lock2(&m_mutex > &other.m_mutex ?
m_mutex : other.m_mutex);
m_value = other.m_value;
return *this;
}
这不应该更新为:
// new boost thread
const counter& operator=(const counter& other){
if (this == &other)
return *this;
boost::unique_lock<boost::mutex> l1(m_mutex, boost::defer_lock);
boost::unique_lock<boost::mutex> l2(other.m_mutex, boost::defer_lock);
boost::lock(l1,l2);
m_value = other.m_value;
return *this;
}
最佳答案
首先,我假设问题是关于在锁定多个任意互斥锁时避免死锁。重要的是始终使用一组互斥体在整个代码中使用相同 排序约定。如果你能保证互斥锁 A 总是先于 B,B 总是先于 C,A 总是先于 C,你就可以避免死锁。
在第一个代码示例中,惯例是首先锁定具有较低内存地址的互斥锁。这会很好地工作,因为地址排序是不变的。第二个版本是 official Boost method避免死锁。该文档未指定内部执行的排序。我不建议在源代码中查找它并在您的代码中的其他地方使用此信息 - 如果库发生变化,它可能会巧妙地破坏一些东西。
如果您是从头开始(您之前在代码中一次持有的互斥锁不超过一个),那么使用 Boost 的方法绝对更可取——您不必担心确切的顺序,只要你每次都让它提升。如果您的其余代码使用内存排序,您必须使用它。如果您的代码完全使用其他约定,您也需要在此处应用它。在任何情况下,您都不应在可能同时持有的任何一组锁中混合约定,这只会带来麻烦。
回答评论中的问题:
自定义锁排序方案在某些情况下很有用,特别是如果您需要长时间持有一些锁 (A),而一些锁 (B) 只是短暂持有,同时持有很长时间一。例如,如果您需要在 A 类型的对象上运行长时间的作业,这会短暂地影响 B 的许多实例。惯例是始终先获取 A 的锁,然后获取 B 的锁对象:
void doStuff(A& a, std::list<B*> bs){ boost::unique_lock<boost::mutex> la(a.mutex); // lock a throughout for (std::list<B*>::iterator ib = bs.begin(); ib != bs.end(); ++ib) { // lock each B only for one loop iteration boost::unique_lock<boost::mutex> lb(ib->mutex); // work on a and *ib // ... }}
您可能能够在每次循环迭代之间放弃对 A 的锁定并使用 Boost 的/C++0x 的锁定顺序,但是根据 doStuff() 的作用,这可能会使算法更复杂或困惑。
另一个例子:在对象不一定位于同一内存位置的运行时环境中(例如,由于复制垃圾收集),依赖内存地址进行排序是不可靠的。因此,您可以为每个对象提供一个唯一的 ID,并根据 ID 顺序进行锁定排序。
关于c++ - 具有不可复制的 boost::mutex 的类的赋值运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4791804/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!