1

我有这个问题,有一个Manager会创建几个Workers来做一些工作,每个worker会触发一个线程,代码如下:

void Manager::create_workers(int n)
{
    _workers_vec.push_back( Worker() );  //save workers in Manager::_workers_vec
    _workers_vec.back().start();  //call the newly created worker's start() to fire a thread
}

void Worker::start()
{
    pthread_create(&_thread_id, NULL, routine, this);  //here is the problem
}

问题是,Worker的线程例程将this作为例程参数以使用 的某些数据成员Worker,但是Worker对象被创建并推回Manager::_workers_vec,当_workers_vec的容量不足以容纳更多Worker对象时,它必须扩展,在此期间旧Worker对象将被复制到新分配的空间,然后被销毁。

这将导致Segment fault, 因为线程routine正在运行并this用作传入的参数,并且在' 扩展this期间被破坏。vector

除了_workers_vecvector<Worker>to更改之外vector<Worker *>,关于如何处理routine' 传入参数的任何更好的想法?

4

3 回答 3

2

好吧,我想你已经得到了答案 - 指针。除此之外但类似的是涉及某种智能指针,例如 boost::shared_ptr 或 std::shared_ptr (如果您可以使用 C++11 标准)。

于 2012-08-10T05:52:26.980 回答
2

这取决于您为什么要使用向量。您可以使用 std::deque 代替,双端队列在增长时不会重新分配,数据存储在块中,当它增长超出其容量时,新的块将添加到双端队列中。

因此,双端队列的数据不是连续的,因此如果您担心在编译时知道容器的大小,则可以使用 std::array,或者如果您在运行时知道它,则可以使用 std::vector。 reserve() 分配所需的内存量。

如果您不需要对容器进行持续时间访问,也可以使用链表。

或者,如果您在 C++11 或 std::shared_ptr 中,则可以使用带有 std::unique_ptr 的向量。

于 2012-08-10T06:05:42.377 回答
0

我希望你能解释为什么你不想要矢量。我相信每个解决方案都会在某个时候使用指针。您可以将容器更改为列表而不是向量,但这实质上意味着使用指针并在堆上分配每个 Worker。

于 2012-08-10T05:55:42.220 回答