boost thread:对象被释放后修改

Posted

技术标签:

【中文标题】boost thread:对象被释放后修改【英文标题】:boost thread: object modified after being freed 【发布时间】:2016-08-21 10:57:22 【问题描述】:

我正在尝试使用 boost 线程创建一个简单的多线程应用程序。基本上我必须计算大约 100 个东西,并且想一次将它分成 8 个线程。唯一棘手的方面是我需要将指针传递给工作人员,然后获取一些返回值。在下面的示例中,指针只是一个浮点数,但在我的实际应用程序中,它是一个更大的类。这是段错误。我做错了什么?

EDIT作为独立文件编写:

#include <iostream>
#include <vector>
#include <boost/thread.hpp>

using namespace std;

class Worker 
public:
  Worker(boost::atomic<int> & threads,
         boost::mutex & mutex,
         boost::condition_variable & condition):
    threads_(threads), mutex_(mutex), condition_(condition)
  void do_stuff(int num, float * num2)
    results_.reserve(num);
    for (int i=0;i<num;i++)
      results_.push_back(*num2);
    
    boost::mutex::scoped_lock lock(mutex_);
    threads_--;
    condition_.notify_one();
  
  std::vector<float> results_;
private:
  boost::atomic<int> & threads_;
  boost::mutex & mutex_;
  boost::condition_variable & condition_;
;

int main()
  int ntasks = 25;
  std::vector<Worker> workers;
  workers.reserve(ntasks);
  boost::thread_group thread_group;
  boost::mutex mutex;
  boost::condition_variable condition;
  boost::atomic<int> threads(0);
  float * bean;
  *bean = 3.14159;
  for(int iz=0;iz<ntasks;iz++)
    boost::mutex::scoped_lock lock(mutex);
    while (threads >= 8) condition.wait(lock);
    Worker w = Worker(threads, mutex, condition);
    workers.push_back(w);
    boost::function<void()> th_func = boost::bind(&Worker::do_stuff,
                                                  &workers.back(),5,bean);
    boost::thread * thread = new boost::thread(th_func);
    thread_group.add_thread(thread);
    threads++;
  
  thread_group.join_all();

  //inspect the results
  for (int iw=0;iw<workers.size();iw++)
    for (int it=0;it<5;it++)
      cout<<workers[iw].results_[it]<<" ";
    
    cout<<endl;
  

  return 0;

在我的 Mac 上编译:

g++ test.cpp -o thread -I/usr/local/include -L/usr/local/lib -lboost_thread-mt -lboost_system-mt

【问题讨论】:

对于此类问题,请随时发帖minimal reproducible example 当您将&amp;w 传递给新线程时,它会在当前迭代结束时超出范围。您应该传递对象的副本或在新线程运行时不会超出范围的变量的地址,例如在保留足够空间后传递 &workers.back() 以便以后的 push_back 调用不会重新分配数组内部工人。另外,您需要等待线程完成写入结果,方法是在读取它们之前销毁 thread_group 或其他东西。 如果你在linux上,我建议使用valgrind和helgrind工具,它会发现线程同步问题。 @m.s.我把它写成一个完整的例子(它为我编译但有段错误! 你有 *bean= 3...; bean 不指向任何东西,您需要先为 bean(不是 *bean)分配一个值。尝试类似float beanValue; float *bean = &amp;beanValue; 【参考方案1】:

你有*bean = 3.14159; bean 没有指向任何东西,你需要先给bean(不是*bean)赋值。尝试类似

float beanValue;
float *bean = &beanValue;
*bean = 3.14159;

【讨论】:

以上是关于boost thread:对象被释放后修改的主要内容,如果未能解决你的问题,请参考以下文章

对象可能在被释放后被修改

使用 boost :: thread 开了一个线程,如何判断该线程是不是进行完毕? 且如何释放该进程所用的资源?

什么时候 boost::shared_ptr 可能不会被释放?

在持有 boost::interprocess::scoped_lock 时休眠会导致它永远不会被释放

iPhone - 如果在自动释放后保留会发生啥?

释放对象后调用方法?