【问题标题】:c++ tuples, vector and threads codec++元组、向量和线程代码
【发布时间】:2012-07-20 08:45:02
【问题描述】:

我有这个代码:

   void threaded_function(Model_factory &mf, ppa::Node *root)
{

  boost::mutex::scoped_lock lock(result_mutex);
  typedef  vector<boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> >
  ::iterator traveling;

  if(!running_jobs.empty())
  {
      cout << "size of running " << running_jobs.size() << endl;
      boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> tuple_to_check = 
      running_jobs.front();
      running_jobs.pop();

      cout << "poping this object from running_jobs" << tuple_to_check << endl;
      cout << "new size of running " << running_jobs.size() << endl;

      lock.unlock();
      ppa::Node *tuplets_father = boost::get<0>(tuple_to_check);
      ppa::Node *first_son = boost::get<1>(tuple_to_check);
      ppa::Node *second_son = boost::get<2>(tuple_to_check);
      bool is_this_done = boost::get<3>(tuple_to_check);

      tuplets_father->start_alignment_new(&mf);

      lock.lock();
      cout << "size of the wait " << wait.size() << endl;

       boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool> new_tuple
       = boost::make_tuple(tuplets_father, first_son, second_son, true);
       wait.push_back(new_tuple);
       cout << "pushing this object to waiting list" << new_tuple << endl;

不必滚动的空间

       cout << "new size of the wait " << wait.size() << endl;  


     lock.unlock();

     lock.lock();

       for(traveling i = wait.begin(); i != wait.end(); i++)
      {
          if(boost::get<3>(*i) == true)
          {


              cout << "found in here pushing to running jobs " << *i <<  endl;
              boost::tuple<ppa::Node*, ppa::Node*, ppa::Node*, bool>  tuple = *i;
              wait.erase(i);
              running_jobs.push(tuple);



          }
      }
       lock.unlock();

  } 

  else
  {

      boost::this_thread::yield();

  } 

这是我的一部分输出:

 found in here pushing to running jobs (0 0x1dd00000142 0xffffffff00000143 1)    
 found in here pushing to running jobs (0 0 0 66)                                
found in here pushing to running jobs (0 0 0x1e000000142 67)                    
found in here pushing to running jobs (0 0x1e100000142 0xffffffff00000143 1)    
found in here pushing to running jobs (0 0 0 66)                                
found in here pushing to running jobs (0 0 0x1e400000142 67)                    
found in here pushing to running jobs (0 0x1e500000142 0xffffffff00000143 1)    
found in here pushing to running jobs (0 0 0 66)                                
found in here pushing to running jobs (0 0 0x1e800000142 67)                    
found in here pushing to running jobs (0 0x1e900000142 0xffffffff00000143 1)    
found in here pushing to running jobs (0 0 0 66)                                
found in here pushing to running jobs (0 0 0x1ec00000142 67)

它会永远消失,我想知道错误在哪里,是否与逻辑有关?很可能是的,但我可以换一双新眼睛,谢谢。

【问题讨论】:

  • 您可能应该尝试将示例的大小减小到出现问题的最小尺寸。
  • I wonder where is the mistake, is it with the logic - 我们也是。也许它应该永远运行?谁知道
  • 不,不是,它应该在没有更多等待向量时结束。
  • 嗯好的,我下次试试。 @迈克尔安德森

标签: c++ multithreading boost vector tuples


【解决方案1】:

您的代码通过调用使vector::iterator i 无效

wait.erase(i);

然后它增加无效的i 并使用它来确定它是否应该跳出for 循环。

您应该改用std::partition()。整个 for 循环可以替换为:

traveling running_jobs = 
                   std::partition( wait.begin(), wait.end(), is_not_running );

running_jobs.insert( running_jobs, wait.end() );

wait.erase( running_jobs, wait.end() );

is_not_running 将是您创建的函数。这也会将复杂度从 O(n2) 降低到 O(n)。

【讨论】:

  • 谢谢,但为什么要 travel::iterator?我没明白,还有什么是 is_not_running a bool 或 func。
  • @user1423656:我的答案中的链接解释了为什么partition 返回一个迭代器,以及is_not_running 需要是什么。
  • 嗨,这个 travel::iterator 给了我,这个:main.cpp:171: error: 'iterator' is not a member of 'threaded_function(ppa::Model_factory&, ppa::Node* )::traveling',有什么帮助吗?
  • 好的,我正在取得进展,这是另一个错误错误:'class threaded_function(ppa::Model_factory&, ppa::Node*)::traveling' has no member named 'insert,insert 显然没有存在于 vec 迭代器中
  • @user1423656 听起来您有一个新问题要问。尝试用展示您问题的最小代码示例提出问题。如果你这样做,你可能会得到更多帮助。
【解决方案2】:

您可能应该使用分区解决方案,但如果您只是想修复您的代码,您应该更改您的 for 循环以正确递增 i,即:

for(traveling i = wait.begin(); i != wait.end();)
...
if (...)
{ 
    ...
    i = wait.erase(i);
    ...
}
else
{
     i++;
}

【讨论】:

  • 虽然擦除只删除了向量,但为什么会弄乱迭代器指针?谢谢(:
  • 没有。擦除将删除元素并为您提供下一个元素的有效迭代器(如果没有,则为“结束”)。被移除元素的迭代器不再有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
  • 1970-01-01
  • 2020-02-04
  • 1970-01-01
  • 2016-03-26
相关资源
最近更新 更多