2

I am learning how to use std::thread in standard C++, and I can't solve one problem with std::mutex.

I am running 2 threads with simple functions that show a message in CMD. I want to use a std::mutex, so that one thread will wait until the other threat stops using the buffer.

When I use the functions everything works fine, but with the functors I have a problem:

error C2280: 'std::mutex::mutex(const std::mutex &)' : attempting to reference a deleted function

What am I doing wrong?

#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)));
}
Niall
  • 30,036
  • 10
  • 99
  • 142
user3808229
  • 29
  • 1
  • 6
  • See this: http://stackoverflow.com/questions/21409439/error-c2280-attempting-to-reference-a-deleted-function – hauron Aug 27 '14 at 08:23
  • The error states that you are trying to copy a mutex (calling the copy constructor), which obviously is not allowed. – stefaanv Aug 27 '14 at 08:25
  • but i'm do the same like with function but inside the class. So where is the problem?? – user3808229 Aug 27 '14 at 08:34

2 Answers2

2

You actually have two problems. The compilation error is because the function objects are copied, but the embedded mutex doesn't have a valid copy-constructor so you get an error. Instead you have to create an instance of your object, and pass the member function and a pointer to the object:

func f1;
thread_guard t1(std::thread(&func::operator(), &f1));

Note that this doesn't really make it useful to use a function in this case.


The other problem is that each functor object have it's own mutex, so the two threads will run completely independent of each other.

If you, for example, make the mutex global, then you also solve the first problem, and can use the functor without problems.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

In your code each function owns a mutex. These are different mutexes, and really they don't guard anything.

The problem is that a function needs to be copyable and mutexes are not. If the function needs to lock a mutex it is usually to some shared resource and you'd pass this mutex by reference to your functor.

Create the mutex outside, e.g. in main(), then

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;
        }
    }     
};

similar for func2

int main(void)
{
   std::mutex mutex;
   thread_guard t1( (std::thread( func( mutex) )) );
   thread_guard t2( (std::thread( func2( mutex ) )) );

}

CashCow
  • 30,981
  • 5
  • 61
  • 92