程序输出有时只出现在多线程程序中
Program output appears only sometimes in multi-threaded program
我正在使用boost线程来并行化程序中的计算。控制器对象管理计算作业和结果。我创建了一组工作线程,它们从控制器对象中获取作业,而主线程显示结果。结果需要按正确的顺序显示。为了实现这一点,我在std::deque
中使用了boost futures。CCD_ 2将新的CCD_ 3添加到deque的末尾并返回指针。GetNextResult()
从队列的前端获取一个结果。如果还没有准备好结果,它就会阻塞调用线程。
我的控制器类的重要部分:
class Controller
{
public:
Controller();
boost::shared_ptr<boost::promise<Results> > GetNewJob();
Results GetNextResult();
class NoJobsLeft{};
class NoResultsLeft{};
private:
bool JobsLeft() const;
bool ResultsLeft() const;
std::deque<boost::shared_ptr<boost::promise<Results> > > queue_;
boost::mutex mutex_;
boost::condition_variable condition_;
};
Worker功能:
void DoWork()
{
try
{
while(true)
{
boost::shared_ptr<boost::promise<Results> >
promise(controller.GetNewJob());
//do calculations
promise->set_value(results);
}
}
catch(NoJobsLeft)
{
}
}
主程序代码:
Controller controller(args);
boost::thread_group worker_threads;
for (unsigned i = 0; i < n_cpus; ++i)
worker_threads.create_thread(DoWork);
try
{
while(true)
{
Results results = controller.GetNextResult();
std::cout << results;
std::cout << std::endl;
}
}
catch(NoResultsLeft)
{
}
worker_threads.join_all();
有时这样做很好,所有结果都会显示出来但很多时候我根本看不到任何输出
我不在工作线程中使用cout
。
GetNewJob()
、GetNextResult()
:的实现
boost::shared_ptr<boost::promise<Results> > Controller::GetNewJob()
{
boost::lock_guard<boost::mutex> lock(mutex_);
if (!JobsLeft())
throw NoJobsLeft();
//determine more information about the job, not important here
queue_.push_back(boost::make_shared<boost::promise<Results> >());
condition_.notify_one();
return queue_.back();
}
Results Controller::GetNextResult()
{
boost::shared_ptr<boost::promise<Results> > results;
{
boost::unique_lock<boost::mutex> lock(mutex_);
if (!ResultsLeft())
throw NoResultsLeft();
while(!queue_.size())
{
condition_.wait(lock);
}
results = queue_.front();
queue_.pop_front();
}
return results->get_future().get();
}
bool Controller::ResultsLeft() const
{
return (queue_.size() || JobsLeft()) ? true : false;
}
在没有看到任何输出的情况下,它可能会抛出NoResultsLeft
,因为第一次通过时队列中没有任何内容。另一种可能性是,它最初未能将内容添加到队列中,或者抛出NoJobsLeft
。将std::cout
语句添加到捕获块中可能有助于识别正在发生的事情
但是,如果结果不能异步显示,那么就没有理由使用该机制——您不妨全部等待。线程的完成顺序无法保证,只能保证通过boost::promise
将结果添加到队列的顺序,因此您必须在GetNextResult
中进行阻塞,至少直到第一个线程完成为止。
如果你想按顺序显示结果,你的控制器可以以相同的方式收集所有结果,并在一切就绪时激发boost::function
以按正确的顺序显示结果。
编辑:
BTW while(!queue_.size())
实际上应该是while(queue_.empty())
,而从技术上讲,任何非零的东西都被解释为真正的方法,命名为size()
、length()
等,当用作if条件时,看起来真的很难看。return (queue_.size() || JobsLeft()) ? true : false;
也是如此,它可能是return (!queue.empty() || JobsLeft());
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 通过安装信号处理程序关闭多线程应用程序
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- C++多线程程序:变量定义为类成员的隔离错误
- 多线程 gtkmm 应用程序最简单的示例
- 将数组作为多线程应用程序中函数的返回传递
- 修改多线程应用程序中的对象
- 在以读取为主的多线程程序中,可以使用原子来减少锁定吗
- 多线程程序中的分段故障和gdb回溯上的不完整信息
- 多线程程序卡在优化模式下,但在 -O0 中正常运行
- 多线程 C++11 应用程序中的同步
- 多线程Windows GUI应用程序中的死锁
- 在使用 std::cout 和多线程程序中如何避免数据竞争<iomanip>?
- 控制多线程程序中的输出流
- C++多线程应用程序将永远挂起
- 具有多线程应用程序的 Nanomsg 无阻塞双向套接字
- C++从多线程 CPU 程序迁移到 GPU
- C++应用程序多线程中的锁定方法