2016-11-08 129 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成为对象的静态私有成员。然而,这会破坏我的互斥锁的目的,因为我希望它是逐个对象而不是类变量。

这只是不好的互斥体使用?我应该重新考虑这整个应用程序吗?

编辑:

我刚刚发现condition_variable这应该成为我的目的好了很多有线程等待,直到有东西居然在双端队列醒来从双端队列弹出,并在打印之前。我看到的所有示例都将这些互斥体和condition_variable对象定义在全局范围内。在我看来,这看起来非常...不是面向对象的。即使直接来自Boost的例子也表明它是以这种方式完成的。这真的是其他人如何使用这些对象吗?

+1

然后让您的课程不可复制。 '删除'复制构造函数和指派操作符。 –

+1

不要复制编译器消息,复制并粘贴未编辑的消息,包括他们的行号。指出来源中的违规行。 –

+0

定义您自己的复制构造函数,您不复制该互斥量。 http://www.boost.org/doc/libs/1_61_0/doc/html/thread/thread_management.html#thread.thread_management.thread.callable_constructor –

回答

2

你是对的,printToStringStringQueue作为参考。你的问题在于boost::thread按价值论据。迫使它参照接受的参数,您将需要修改的东西:

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

顺便说一句,从C++ 11日起,线程是标准库的一部分。您应该使用std::thread instead

+0

我使用的古代编译器只支持C++ 11的实验形式。 –

+0

作为任何使用boost的好理由 – doron