我在pthreads中实现了一个粒子交互模拟器,我在pthreads代码中不断出现分段错误。故障发生在以下循环中,每个线程在我的thread_routine的每个时间步结束时执行:
for (int i = first; i < last; i++)
{
get_id(particles[i], box_id);
pthread_mutex_lock(&locks[box_id.x + box_no * box_id.y]);
//cout << box_id.x << "," << box_id.y << "," << thread_id << "l" << endl;
box[box_id.x][box_id.y].push_back(&particles[i]);
//cout << box_id.x << box_id.y << endl;
pthread_mutex_unlock(&locks[box_id.x + box_no * box_id.y]);
}
奇怪的是,如果我取消注释(无论哪一个)或两个couts,程序按预期运行,没有错误发生(但这显然会杀死性能,并不是一个优雅的解决方案),给出正确的输出。
框是全局声明的 矢量&lt;矢量&lt;矢量&lt; particle_t * GT; &GT; &GT;框 表示将我((方形)域分解为方框。
当循环开始时,对于所有i,j,框[i] [j] .size()已被设置为零,并且循环应该将粒子放回到框结构中(get_id函数给出正确的结果,我已经检查过了)
数组pthread_mutex_t锁被声明为全局
pthread_mutex_t * locks
,
并且大小由线程0设置,并且在创建其他线程之前由线程0初始化锁:
locks = (pthread_mutex_t *) malloc( box_no*box_no * sizeof( pthread_mutex_t ) );
for (int i = 0; i < box_no*box_no; i++)
{
pthread_mutex_init(&locks[i],NULL);
}
你知道可能导致这种情况的原因吗?如果处理器的数量设置为1,代码也会运行,看起来我运行的处理器越多,seg故障发生得越早(它在两个处理器上运行整个模拟一次,但这似乎是一个例外)
由于
答案 0 :(得分:1)
这只是一个有根据的猜测,但如果你对所有方框都使用一个锁,问题就会消失:push_back
必须通过std::allocator
模板分配内存。我认为allocator
不保证是线程安全的,我认为它不能保证被分区,每个vector
一个。 (基础operator new
是线程安全的,但allocator
通常会使用块切片技巧来分摊operator new
的费用。)
使用reserve
提前为所有向量预先分配空间是否切实可行,使用保守估计每个盒子中有多少粒子会被卷入?这是我尝试的第一件事。
我尝试的另一件事是对我们知道可行的所有方框使用一个锁,但是在for
循环之外移动锁定/解锁操作,以便每个线程都将其所有项目存储在一旦。这实际上可能比你想做的更快 - 更少锁定颠簸。
答案 1 :(得分:0)
box
和box[i]
向量是否已正确初始化?您只说设置了最里面的向量集。否则看起来box_id
的{{1}}或x
组件是错误的并且在您的某个阵列的末尾运行。
看起来崩溃的部分是什么?