how to initialize a unique lock that has already been declared in c++?

835 Views Asked by At

I created a class and I declared an array of unique locks and an array of mutexes as private variables. My question is how do I connect the two of them in the constructor of the class?

header file:

#include <iostream>
#include <mutex>
#include <string>

#define PHILO_NUM 5
class philosophers
{
private:
    std::mutex _mu[5];
    std::unique_lock<std::mutex> _fork[5], _screen;
    std::mutex _screenMutex;
public:
    philosophers();
};

c++ file:

#include "philosophers .h"

philosophers::philosophers()
{
    for (int i = 0; i < PHILO_NUM; i++)
    {
        // Somehow connect this->_forks[i] and this->_mu[i]
    }
// At the end connect this->_screen and this->_screenMutex
}
1

There are 1 best solutions below

0
n314159 On

It is not easy to say what you should be doing since you do not tell what you want to do. I think you mixed locks and mutexes a bit up. There is no reason to share the locks (as you try to do here). You need to share the mutexes, but one mutex can be associated with arbitrary many std::unique_locks (but only one of them can lock the mutex at the same time).

So, I would implement your class as follows:

#include <mutex>

constexpr size_t PHILO_NUM = 5;
class philosophers
{
private:
    std::mutex _mu[PHILO_NUM];
    std::mutex _screenMutex;
public:
    philosophers() = default; // Nothing to do here
 
    std::unique_lock grab_fork(size_t index) {
        return std::unique_lock (_mu[index]);
    }
};

So, if someone grabs a fork, they can use it as long as they hold a lock to that fork. An example use would look like this:

philosophers p;
void eat() {
    auto lock = p.grab_fork(3);
    // Now I can eat
    lock.unlock(); // Not really necessary, lock will release the mutex, when it is destroyed at the end of the scope
}