2016-11-08 5 views
1

У меня есть класс, который содержит 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 показывают, что это делается таким образом. Разве это так, как другие люди используют эти объекты?

+1

Сделайте свой класс не скопированным тогда. 'delete' copy constructor и оператор присваивания. –

+1

Не пересказывать сообщения компилятора, копировать и вставлять их неотредактированными, включая номера строк. Укажите строки нарушения в источнике tge. –

+0

Определите свой собственный конструктор копирования, в котором вы не копируете мьютексы. http://www.boost.org/doc/libs/1_61_0/doc/html/thread/thread_management.html#thread.thread_management.thread.callable_constructor –

ответ

2

Вы считаете, что printToString принимает по ссылке StringQueue. Ваша проблема заключается в том, что boost::thread принимает свои аргументы по значению. Для того, чтобы заставить его принять аргументы по ссылке вам нужно изменить вещи:

boost::thread the_thread(printTheStrings, boost::ref(str_deque)); 

как в сторону от C++ 11 и далее, потоки являются частью стандартной библиотеки. Вероятно, вы должны использовать std::thread instead

+0

Я использую древний компилятор, который поддерживает C++ 11 только в экспериментальной форме , –

+0

Как хорошая причина использовать boost как любой – doron

Смежные вопросы