我想知道按值传递事物时可变剪切的工作原理。我会在调用函数之前锁定互斥锁,然后在进入函数后在函数内部解锁吗?使用线程时,按值传递是否更可取?
Mutex Que_mutex;
queue <char> Que; //access to this must be done with Que_mutex locked
void queSizeCheck(queue<char> quet);
int main() {
//open new threads, which also manipulate Que
//some other code here, where Que.push, Que.pop and Que.front happens at some points
Que_mutex.lock();
queSizeCheck(Que);
}
void queSizeCheck(queue<char> quet) {
Que_mutex.unlock();
if (quet.size() < 3) {
//do something
}
}
我正在使用C ++ 98编写mbed。
答案 0 :(得分:3)
这是在C ++ 98中传递值被破坏的原因之一。
由于要在最短的时间内保持锁定状态,因此在C ++ 11和C ++ 14中,我将首先复制队列,然后解锁互斥锁,然后移动函数(假设queue
是可移动的)。
int main() {
std::unique_lock<Mutex> lock(Que_mutex);
auto copy = Que;
lock.unlock();
queSizeCheck(std::move(copy));
}
由于该问题被标记为C ++ 98,因此我们不能使用移动语义。在这种情况下,我会将复制封装到一个单独的函数中,并依靠编译器足够聪明来应用复制省略:
queue<char> queCopy() {
// lock_guard is C++11 but you can easily write your own C++98 implementation
std::lock_guard<Mutex> lock(Que_mutex);
// hope the compiler is smart enough to directly initialize the parameter
// of queSizeCheck without incurring additional copies
return Que;
}
int main() {
queSizeCheck(queCopy());
}
这依赖于编译器隐藏queCopy
的返回值和queSizeCheck
的参数的副本。最终导致该代码实际上比C ++ 11代码井井有条。从C ++ 17开始,由于强制复制省略,这再次成为更好的解决方案。
所有这些都假设queue
的合理实现,但问题中未显示。
答案 1 :(得分:0)
当然可以。您甚至没有在此处传递mutex
。您使用的是相同的mutex
。
它将被解锁。
即使您在函数中传递了mutex
。它仍然会被解锁。
但是。将mutex
锁定在一个功能中然后将其解锁在另一个功能中是不明智的。
您应该使用这种方法。
mutex.lock()
//... some operations on the data structure
mutex.unlock()
您可以使用lock_guard了解RAII的实现方式。