矢量扩展和线程例程

vector expanding and thread routine

本文关键字:线程 例程 扩展      更新时间:2023-10-16

我有这个问题,有一个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作为传入的参数,并且在vector的扩展过程中this被破坏。

除了将_workers_vecvector<Worker>改为vector<Worker *>之外,关于如何处理routine通过的争论,还有什么更好的主意吗?

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

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

因此,deque的数据不是连续的,所以如果你在编译时知道容器的大小,或者如果你在运行时知道它,你可以使用std::array来分配所需的内存量。

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

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

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