【问题标题】:c++ how to use std::mutex and std::lock_guard with functor?c++ 如何将 std::mutex 和 std::lock_guard 与仿函数一起使用?
【发布时间】: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)));
}

【问题讨论】:

  • 该错误表明您正在尝试复制互斥体(调用复制构造函数),这显然是不允许的。
  • 但我对函数做同样的事情,但在课堂上。那么问题出在哪里??

标签: c++ multithreading c++11


【解决方案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 ) )) );
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 2018-05-11
      相关资源
      最近更新 更多