c++ 如何将 std::mutex 和 std::lock_guard 与仿函数一起使用?
Posted
技术标签:
【中文标题】c++ 如何将 std::mutex 和 std::lock_guard 与仿函数一起使用?【英文标题】:c++ how to use std::mutex and std::lock_guard with functor? 【发布时间】:2014-08-27 08:16:22 【问题描述】:我正在学习如何在标准 C++ 中使用std::thread
,但我无法用std::mutex
解决一个问题。
我正在运行 2 个线程,它们具有在 CMD 中显示消息的简单函数。我想使用std::mutex
,这样一个线程将等到另一个威胁停止使用缓冲区。
当我使用函数时,一切正常,但使用函子时我遇到了问题:
错误 C2280: 'std::mutex::mutex(const std::mutex &)' : 试图引用已删除的函数
我做错了什么?
#include <iostream>
#include <thread>
#include <mutex>
class thread_guard
private:
std::thread m_thread;
public:
thread_guard(std::thread t)
m_thread = std::move(t);
if (!m_thread.joinable())
std::cout << "Brak watku!!!" << std::endl;
~thread_guard()
m_thread.join();
;
class func
private:
std::mutex mut;
public:
void operator()()
for (int i = 0; i < 11000; i++)
std::lock_guard<std::mutex> guard(mut);
std::cout << "watek dziala 1" << std::endl;
;
class func2
private:
std::mutex mut;
public:
void operator()()
for (int i = 0; i < 11000; i++)
std::lock_guard<std::mutex> guard(mut);
std::cout << "watek dziala 2" << std::endl;
;
std::mutex mut2;
void fun()
for (int i = 0; i < 11000; i++)
std::lock_guard<std::mutex> guard(mut2);
std::cout << "watek dziala 1" << std::endl;
void fun2()
for (int i = 0; i < 11000; i++)
std::lock_guard<std::mutex> guard(mut2);
std::cout << "watek dziala 2" << std::endl;
int main(void)
thread_guard t1( (std::thread( func() )) );
thread_guard t2( (std::thread(func2() )) );
//thread_guard t1((std::thread(fun)));
//thread_guard t2((std::thread(fun2)));
【问题讨论】:
看这个:***.com/questions/21409439/… 该错误表明您正在尝试复制互斥体(调用复制构造函数),这显然是不允许的。 但我对函数做同样的事情,但在课堂上。那么问题出在哪里?? 【参考方案1】:你实际上有两个问题。编译错误是因为函数对象被复制,但是嵌入的互斥体没有有效的复制构造函数,所以你得到一个错误。相反,您必须创建对象的实例,并传递成员函数和指向该对象的指针:
func f1;
thread_guard t1(std::thread(&func::operator(), &f1));
请注意,在这种情况下使用函数并没有真正的用处。
另一个问题是每个仿函数对象都有自己的互斥锁,因此两个线程将完全独立运行。
例如,如果你将互斥锁设为全局,那么你也解决了第一个问题,并且可以毫无问题地使用仿函数。
【讨论】:
【参考方案2】:在您的代码中,每个function
都拥有一个互斥锁。这些是不同的互斥体,实际上它们不保护任何东西。
问题是函数必须是可复制的,而互斥体不是。如果函数需要锁定一个互斥锁,它通常是针对某个共享资源的,你可以通过引用你的仿函数来传递这个互斥锁。
在外部创建互斥锁,例如在 main() 中,然后
class func
std::mutex * mutex;
public:
explicit func( std::mutex & m ) : mutex( &m )
void operator()()
for (int i = 0; i < 11000; i++)
std::lock_guard<std::mutex> guard(*mutex);
std::cout << "watek dziala 1" << std::endl;
;
func2 类似
int main(void)
std::mutex mutex;
thread_guard t1( (std::thread( func( mutex) )) );
thread_guard t2( (std::thread( func2( mutex ) )) );
【讨论】:
以上是关于c++ 如何将 std::mutex 和 std::lock_guard 与仿函数一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在 C++ 中仅使用 std::atomic 而不使用 std::mutex 安全地共享一个变量吗?
C++11:基于std::queue和std::mutex构建一个线程安全的队列
C++ 协议缓冲区:常量表达式中的临时非文字类型 'google::protobuf::internal::CallOnInitializedMutex <std::mutex>'