矢量扩展和线程例程
vector expanding and thread routine
我有这个问题,有一个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_vec
从vector<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 。
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- c++类声明时,相同的例程,不同的成员变量类型
- C++为线程工作动态地分割例程
- 子例程,不使用 pow,并带有参数和返回
- 直接在RcppArmadillo中调用LAPACK例程
- 如何将C++子例程链接到 x86 程序集程序?
- PX 转换例程编译问题
- C++中的多线程:连接线程的正确方法
- 成功完成TLS握手后,服务器关闭时出现错误的SSL例程:SSL3_GET_RECORD:错误的版本号
- 只允许授权代码调用库中的例程
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- 调用子例程时类型不匹配
- Posix 线程类和启动例程 (pthread)
- OpenBLAS 只为一个例程设置线程数
- 如何使派生类函数作为线程的启动例程?
- 矢量扩展和线程例程
- 为多线程程序增强非阻塞读写例程
- 传递字符串作为线程启动例程参数:c++
- c++:如何定义类方法作为线程的启动例程(使用pthread库)
- 传递线程例程多个变量和堆栈大小