Мьютекс для частного объекта - глобальный атрибут против - PullRequest
0 голосов
/ 31 января 2020

У меня есть класс Processor, который может получать уведомления об объектах. Уведомленные объекты в конечном итоге обрабатываются в отдельном потоке.

Поскольку очередь используется несколькими потоками, для предотвращения ошибочного поведения необходим мьютекс q_mutex.

class Processor {
    std::queue<int> q;
    void q_processing_thread();    // while true loop - uses the mutex
public:
    void notify(int);  // pushes int to q - uses the mutex
    bool isEmpty() const;     // checks if the queue is empty  - uses the mutex
};

Вопрос:

Должен ли мьютекс быть атрибутом Processor или глобальной переменной?

Концептуально,

  • isEmpty должно быть const так как это не должно изменять объект. Однако это препятствует блокировке мьютекса.
  • мьютекс не имеет значения вне класса, поскольку очередь является частным атрибутом Processor.

Ответы [ 3 ]

3 голосов
/ 31 января 2020

Мьютекс должен быть частью класса.

Вы можете указать его как mutable, чтобы использовать его в const методах.

Class Processor {
    std::queue<int> q;
    mutable std::mutex q_mutex;
    . . .
}
1 голос
/ 31 января 2020

Глобальные переменные обычно не одобряются.

Поскольку в C ++ нет мьютекса-владельца, лучше всего иметь атрибут члена

mutable позволяет изменять его, даже если ваш this is const

class Processor {
    std::queue<int> q;
    mutable std::mutex mtx;
    void q_processing_thread();    // while true loop - uses the mutex
public:
    void notify(int);  // pushes int to q - uses the mutex
    bool isEmpty() const;     // checks if the queue is empty  - uses the mutex
};

Блокировка, как только вам понадобится мьютекс, предпочтительно через std :: lock_guard или scoped_lock.

Не держите его заблокированным больше, чем это необходимо, так как может вызвать проблемы с производительностью

0 голосов
/ 01 февраля 2020

Мьютекс должен быть объявлен с той же областью действия и объемом, что и данные, которые он защищает. Единственными данными в вашем примере является переменная-член q. Итак, , если считать, что q - это то, что вы хотите защитить, тогда мьютекс, предназначенный для защиты q, вероятно, должен быть членом того же класса.

...