使用 boost::mutex 作为 class 的私有成员
Using boost::mutex as a private member of class
我有一个 class,其中包含一个 boost::mutex 作为私有成员。当您调用其中一个 public 函数时,它会被锁定,并在该函数退出时解锁。这是为了提供对对象内部的同步访问。
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;
}
};
这个 class 并不是特别有用,但我只是在玩弄互斥体和线程。
我有一个 main(),它还定义了另一个函数,该函数从 class 弹出字符串并在线程中打印它们。它将重复这 10 次,然后从函数中 return。再一次,这纯粹是为了测试目的。它看起来像这样:
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 成为对象的静态私有成员。但是,这违背了我的互斥体的目的,因为我希望它是逐个对象的,而不是 class 变量。
这只是对互斥量的错误使用吗?我应该重新考虑整个应用程序吗?
编辑:
我刚刚发现 condition_variable 让线程等待直到双端队列中实际存在某些东西,然后再从双端队列中弹出并打印它,这应该更好地满足我的目的。我看到的所有示例都在全局范围内定义了这些互斥锁和 condition_variable 对象。这似乎非常……在我看来不是面向对象的。甚至直接来自 Boost 的示例本身也表明它是通过这种方式完成的。这真的是其他人使用这些对象的方式吗?
你是正确的,printToString
通过引用引用了 StringQueue
。您的问题是 boost::thread
按值获取其参数。要强制它通过引用获取参数,您需要将内容修改为:
boost::thread the_thread(printTheStrings, boost::ref(str_deque));
顺便说一句,从 C++11 开始,线程是标准库的一部分。您可能应该使用 std::thread instead
我有一个 class,其中包含一个 boost::mutex 作为私有成员。当您调用其中一个 public 函数时,它会被锁定,并在该函数退出时解锁。这是为了提供对对象内部的同步访问。
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;
}
};
这个 class 并不是特别有用,但我只是在玩弄互斥体和线程。
我有一个 main(),它还定义了另一个函数,该函数从 class 弹出字符串并在线程中打印它们。它将重复这 10 次,然后从函数中 return。再一次,这纯粹是为了测试目的。它看起来像这样:
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 成为对象的静态私有成员。但是,这违背了我的互斥体的目的,因为我希望它是逐个对象的,而不是 class 变量。
这只是对互斥量的错误使用吗?我应该重新考虑整个应用程序吗?
编辑:
我刚刚发现 condition_variable 让线程等待直到双端队列中实际存在某些东西,然后再从双端队列中弹出并打印它,这应该更好地满足我的目的。我看到的所有示例都在全局范围内定义了这些互斥锁和 condition_variable 对象。这似乎非常……在我看来不是面向对象的。甚至直接来自 Boost 的示例本身也表明它是通过这种方式完成的。这真的是其他人使用这些对象的方式吗?
你是正确的,printToString
通过引用引用了 StringQueue
。您的问题是 boost::thread
按值获取其参数。要强制它通过引用获取参数,您需要将内容修改为:
boost::thread the_thread(printTheStrings, boost::ref(str_deque));
顺便说一句,从 C++11 开始,线程是标准库的一部分。您可能应该使用 std::thread instead