我有这个问题,有一个Manager
会创建几个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_vec
从vector<Worker>
更改为vector<Worker *>
之外,如何更好地了解如何处理routine
传递的参数?
答案 0 :(得分:2)
嗯,我想你已经得到了答案 - 指针。除此之外,类似的是涉及某种智能指针,如boost :: shared_ptr或std :: shared_ptr(如果你可以使用C ++ 11标准)。
答案 1 :(得分:2)
这取决于您为什么要使用矢量。您可以使用std :: deque代替,deque在增长时不会重新分配,数据以块的形式存储,并且当deque超出其容量时会添加一个新的chunk。
deque的数据因此不是连续的,所以如果这是一个问题,如果你在编译时知道容器的大小,你可以使用std :: array,或者如果你在运行时知道它,你可以使用std: :vector.reserve()分配所需的内存量。
如果您不需要对容器进行持续时间访问,也可以使用链接列表。
如果您使用的是C ++ 11或std :: shared_ptr,则可以使用带有std :: unique_ptr的向量。
答案 2 :(得分:0)
我希望你解释为什么你不想要矢量。我相信每个解决方案都会在某些时候使用指针。您可以将容器更改为列表而不是向量,但这实际上意味着使用指针并在堆上分配每个Worker。