我目前正在尝试使用名为boost::thread
的共享互斥锁获得两个mutexCOM
来在CPU上获得相同的处理时间。目前,两个线程都设置为无限运行。一个线程(主线程)只打印出"测试!"而运行Navigation::begin()
功能的另一个线程打印" -----共享功能-----"等待一秒钟,然后打印" ---- - 共享功能现在将结束...... #-"。等待意味着模拟将替换此存根的函数所需的大量处理。无限循环的每次迭代都在循环内由mutexCOM
上的作用域锁定开始。预期的输出应该是无限的以下广告:
testing!
-----shared function-----
----Shared function will now end...-----
testing!
-----shared function-----
----Shared function will now end...-----
不幸的是,我所做的事情导致输出变为:
`
似乎迭代被组合在一起而不是像我期望的那样交错。如果有人能解释这里发生了什么,我会非常感激,因为我对使用互斥锁的线程管理的理解似乎可以使用一些工作。
我唯一的理论是我假设boost处理排队以锁定互斥锁是错误的,并且我需要以某种方式创建我自己的队列以给予线程公平访问以避免饥饿。但是,我对此表示怀疑,因为它基本上会使互斥量变得毫无意义,因为我仍然需要自己处理所有的管理。那时为什么不只是使用信号量?
我的代码如下。仅包含相关代码,因此不必担心缺少类结构。假设所有标头都已正确包含,并且SharedMutex.h包含在两个类中:
SharedMutex.h -
#ifndef SHARED_MUTEX_
#define SHARED_MUTEX_
#include <boost/thread/mutex.hpp>
extern boost::mutex mutexCOM;
#endif
Navigation.cpp -
Navigation::begin() {
boost::mutex::scoped_lock lock(mutexCOM);
cout<< "-----shared function-----" << endl;
sleep(1);
cout<< "----Shared function will now end...-----" << endl;
}
mainclass.cpp -
void mainclass::run() {
this->runNav();
while(1) {
boost::mutex::scoped_lock lock(mutexCOM);
cout << "testing!" << endl;
}
}
void mainclass::runNav() {
//this->nav is an instance of Navigation within mainclass
boost::thread navThread(boost::bind(&Navigation::begin, *(this->nav)));
//this->navPtr is a pointer to the boost::thread for later management
this->navPtr=&navThread;
}
答案 0 :(得分:3)
这是错误的:
// this->navPtr is a pointer to the boost::thread for later management
this->navPtr = &navThread;
你正在那里取一个局部变量的地址。如果稍后使用navPtr
,那就是未定义的行为。相反,只需将线程存储在成员中:请参阅下面的示例。
然而,我对此表示怀疑,因为它基本上会使互斥量变得毫无意义,因为我仍然需要自己处理所有管理
事实上。如果您想要任务排队,请编写它。互斥体并非如此。顾名思义,互斥体仅用于 互斥 ,这是两个代码块(关键部分)做的基本保证。不同时运行。
它不保证任何其他内容。
线程饥饿确实是个问题,可以通过在某些时候引入产量/睡眠来证明:
<强> Live On Coliru 强>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/scoped_ptr.hpp>
#include <iostream>
static boost::mutex mutexCOM;
struct Navigation {
void begin() {
size_t count = 0;
while(++count< 10) {
{
boost::mutex::scoped_lock lock(mutexCOM);
std::cout << "-----shared function-----" << std::endl;
boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
std::cout << "----Shared function will now end...-----" << std::endl;
}
boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); // or boost::this_thread::yield e.g.
}
std::cout << "Navigation::begin() completed\n";
}
};
struct mainclass {
void run() {
size_t count = 0;
this->runNav();
while (++count < (1ull<<20))
{
{
boost::mutex::scoped_lock lock(mutexCOM);
std::cout << "testing!" << std::endl;
}
boost::this_thread::yield();
}
std::cout << "mainclass::run() completed\n";
}
~mainclass() {
if (navThread.joinable())
{
std::cout << "Waiting for Navigation to end...\n";
navThread.join();
}
}
private:
void runNav() {
navThread = boost::thread(boost::bind(&Navigation::begin, *(this->nav)));
}
boost::scoped_ptr<Navigation> nav { new Navigation };
boost::thread navThread;
};
int main() {
mainclass instance;
instance.run();
}
打印:./a.out | uniq -c
1 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
9726 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5501 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5197 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5316 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5913 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5515 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5639 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5352 testing!
1 -----shared function-----
1 ----Shared function will now end...-----
5162 testing!
1 Navigation::begin() completed
995253 testing!
1 mainclass::run() completed
1 Waiting for Navigation to end...