使用pthreads_mutex进行段错误

时间:2011-03-01 20:29:08

标签: c++ pthreads segmentation-fault mutex cout

我在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故障发生得越早(它在两个处理器上运行整个模拟一次,但这似乎是一个例外)

由于

2 个答案:

答案 0 :(得分:1)

这只是一个有根据的猜测,但如果你对所有方框都使用一个锁,问题就会消失:push_back必须通过std::allocator模板分配内存。我认为allocator不保证是线程安全的,我认为它不能保证被分区,每个vector一个。 (基础operator new 是线程安全的,但allocator通常会使用块切片技巧来分摊operator new的费用。)

使用reserve提前为所有向量预先分配空间是否切实可行,使用保守估计每个盒子中有多少粒子会被卷入?这是我尝试的第一件事。

我尝试的另一件事是对我们知道可行的所有方框使用一个锁,但是在for循环之外移动锁定/解锁操作,以便每个线程都将其所有项目存储在一旦。这实际上可能比你想做的更快 - 更少锁定颠簸。

答案 1 :(得分:0)

boxbox[i]向量是否已正确初始化?您只说设置了最里面的向量集。否则看起来box_id的{​​{1}}或x组件是错误的并且在您的某个阵列的末尾运行。

看起来崩溃的部分是什么?