У меня есть класс, который содержит boost :: mutex как частный член. Он блокируется при вызове одной из своих публичных функций и разблокируется при выходе из функции. Это обеспечивает синхронный доступ к внутренним объектам объекта.Использование boost :: mutex как частный член класса
class StringDeque
{
boost::mutex mtx;
std::deque<string> string_deque;
public:
StringDeque() { }
void addToDeque(const string& str_to_add)
{
boost::lock_guard<boost::mutex> guard(mtx);
string_deque.push(str_to_add);
}
string popFromDeque()
{
boost::lock_guard<boost::mutex> guard(mtx);
string popped_string = string_deque.front();
string_deque.pop();
return popped_string;
}
};
Этот класс не предназначен для особо полезного использования, но я просто играю с мьютексами и потоками.
У меня есть main(), который также имеет другую функцию, определяющую, что выставляет строки из класса и печатает их в потоке. Он повторит это 10 раз, а затем вернется из функции. Еще раз, это чисто для тестирования. Это выглядит так:
void printTheStrings(StringDeque& str_deque)
{
int i = 0;
while(i < 10)
{
string popped_string = str_deque.popFromDeque();
if(popped_string.empty())
{
sleep(1);
continue;
}
cout << popped_string << endl;
++i;
}
}
int main()
{
StringDeque str_deque;
boost::thread the_thread(printTheStrings, str_deque);
str_deque.addToDeque("Say your prayers");
str_deque.addToDeque("Little One");
str_deque.addToDeque("And Don't forget My Son");
str_deque.addToDeque("To include everyone");
str_deque.addToDeque("I tuck you in");
str_deque.addToDeque("Warm within");
str_deque.addToDeque("Keep you free from sin");
str_deque.addToDeque("Until the sandman he comes");
str_deque.addToDeque("Sleep with one eye open");
str_deque.addToDeque("Gripping your pillow tight");
the_thread.join();
}
Ошибка, которую я получаю, заключается в том, что boost :: mutex не подлежит копированию. Функция printTheStrings() принимает ссылку, поэтому я немного смущен, почему она пытается скопировать объект.
Я немного почитал об этом, и одно из решений, которое я продолжаю читать, - сделать boost :: mutex статическим частным членом объекта. Тем не менее, это нарушает цель моего мьютекса, поскольку я хочу, чтобы он был на основе объекта за объектом, а не на переменную класса.
Это просто плохое использование мьютексов? Должен ли я просто переосмыслить все это приложение?
EDIT:
Я только что обнаружил condition_variable, который должен служить своей цели гораздо лучше иметь поток в состояние ожидания до тех пор, пока что-то на самом деле в дека до пробуждения поп из дека и распечатать его. Все примеры, которые я вижу, определяют эти мьютексы и объекты condition_variable в глобальной области. Это кажется очень ... не объектно-ориентированным, на мой взгляд. Даже примеры из самого Boost показывают, что это делается таким образом. Разве это так, как другие люди используют эти объекты?
Сделайте свой класс не скопированным тогда. 'delete' copy constructor и оператор присваивания. –
Не пересказывать сообщения компилятора, копировать и вставлять их неотредактированными, включая номера строк. Укажите строки нарушения в источнике tge. –
Определите свой собственный конструктор копирования, в котором вы не копируете мьютексы. http://www.boost.org/doc/libs/1_61_0/doc/html/thread/thread_management.html#thread.thread_management.thread.callable_constructor –