1

我正在 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,程序会按预期运行,不会发生错误(但这显然会降低性能,并且不是一个优雅的解决方案),给出正确的输出。

box 是一个全局声明的 vector < vector < vector <particle_t*> > > box,它表示将我的(方形)域分解为框。

循环开始时,所有 i、j 的 box[i][j].size() 已设置为零,并且循环应该将粒子放回盒子结构中(get_id 函数给出正确的结果,我已检查)

数组 pthread_mutex_t locks 被声明为全局

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,代码也会运行,而且似乎我运行的处理器越多,段错误发生的越早(它已经在两个处理器上运行了整个模拟一次,但这似乎是例外)

谢谢

4

2 回答 2

1

这只是一个有根据的猜测,但基于如果您对所有盒子使用一个锁,问题就会消失:push_back必须分配内存,它通过std::allocator模板完成。我不认为allocator它保证是线程安全的,我也不认为它保证是分区的,每个分区一个vector。(底层operator new 线程安全的,但allocator通常会使用块切片技巧来摊销operator new的成本。)

您是否可以reserve提前为所有向量预分配空间,使用保守估计每个盒子中将有多少粒子结束?这是我要尝试的第一件事。

我要尝试的另一件事是对所有盒子使用一个锁,我们知道这是可行的,但是将锁定/解锁操作移到for循环之外,以便每个线程一次存储其所有项目。这实际上可能比您尝试做的更快——更少的锁抖动。

于 2011-03-01T22:30:21.503 回答
0

box和向量是否box[i]正确初始化?您只说设置了最里面的一组向量。否则,它看起来像box_id's xor ycomponent 是错误的,并且在您的阵列之一的末尾运行。

它在外观的哪个部分崩溃?

于 2011-03-01T20:55:18.743 回答