【问题标题】:Passing a deque to a new pthread将双端队列传递给新的 pthread
【发布时间】:2012-04-30 22:47:06
【问题描述】:

我在 pthread 中有一段代码(让我们将此线程称为 a),并且我希望生成一个新的 pthread(让我们将此线程称为 b)。线程b 需要传递一个双端队列,我有以下代码:

void* process_thread_b(void* arg)
{              
  deque<string> *ptr = (deque<string>*)arg;
  cout << "Size -" << ptr->size() << endl;

  deque<string>::iterator it;
  for(it = ptr->begin(); it != ptr->end(); it++)
  {
    cout <<(*it) << endl;
  }
}

以上代码为线程b's代码。它传递了一个双端队列并正确打印出大小。当我尝试打印出它的任何元素时,我得到:

terminate called after throwing an instance of 'std::bad_alloc'
 what():  std::bad_alloc
Abort (core dumped)

当我生成 pthread 时,我使用下面的代码...

 deque<string> myDeque;

 // Add strings to deque here...

 pthread_t dispatchCommands;
 pthread_create(&dispatchCommands, NULL, &process_thread_b, (void*)&myDeque);

底部代码发生在线程a。为什么当我尝试打印出双端队列的一个元素时,我得到一个错误,但我可以得到它的大小?

【问题讨论】:

    标签: c++ thread-safety pthreads deque


    【解决方案1】:

    pthread_create 将在您的线程函数开始执行之前很久就返回。你的deque 早就被销毁了。您需要在堆上创建它。

    【讨论】:

    • 或者确保master没有退出当前作用域(或者deque在线程终止前没有退出的作用域)。 (两者都是更常见的解决方案)。
    • 当您需要将对象传递给将“拥有”它的线程时使用的一个很好的习惯用法是使用new 分配它,将指向它的指针传递给线程的启动函数,然后完成后有线程delete。您可以让线程的启动函数完成所有工作,如下所示:void* MyThreadFunction(void *foo) { reinterpret_cast&lt;Bar*&gt;(foo); foo-&gt;RealWorkFunction(); delete foo; return NULL; }
    • 编写多线程应用程序时使用的一个好习惯是动态分配所有内容。可悲的是,在本网站和网络上都有很多不合格的“总是在堆栈上分配,不要使用 new()”建议。开发人员遵循此建议并最终导致启动崩溃(如 OP)、当线程尝试访问 crt 已破坏的静态对象时出现关闭问题,以及介于两者之间的各种问题。
    • @MartinJames:这是非常不正确的。不使用new 并不意味着“不要动态分配”,而是意味着“不要将自己暴露在原始new 的可怕异常和内存不安全中”,这是完全不同的两件事。
    【解决方案2】:

    我认为这是因为您试图将对牌组的引用转换为 void*,试试这个:

     deque<string> * myDeque = new deque<string>();
    

    然后使用 -> 来访问它的功能。

    然后您可以将 myDeque 直接转换为 void 指针,它会保持初始化状态。

    即。 :

     (void*)myDeque
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-06-01
      • 1970-01-01
      • 2011-02-09
      • 2020-05-24
      • 2011-12-11
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多