Laz*_*zer 3 c++ deadlock pthreads cilk cilk-plus
我很惊讶地看到pstack这段代码导致死锁!我没有看到同样的理由.
pthread_mutex_t lock;
_Cilk_for (int i = 0; i < N; ++i) {
int ai = A[i];
if (ai < pivot) {
pthread_mutex_lock(&lock);
A[ia++] = ai;
pthread_mutex_unlock(&lock);
}
else if (ai > pivot) {
pthread_mutex_lock(&lock);
A[ib++] = ai;
pthread_mutex_unlock(&lock);
}
else {
pthread_mutex_lock(&lock);
A[ic++] = ai;
pthread_mutex_unlock(&lock);
}
}
Run Code Online (Sandbox Code Playgroud)
我只是使用互斥锁来确保对A的访问是原子的和序列化的.
如果函数内部有代码,则表示您没有正确初始化互斥锁.您需要将其设置为PTHREAD_MUTEX_INITIALIZER(对于简单的默认互斥锁)或对其执行操作pthread_mutex_init()(对于更复杂的要求).如果没有正确的初始化,你就不知道互斥体的起始状态 - 它很可能处于锁定状态,因为发生在该位置的堆栈上看起来就像一个锁定的互斥锁.
这就是为什么它总是需要以某种方式初始化,以便初始状态毫无疑问.
您可能遇到的另一个潜在问题是:
int ai = A[i];
Run Code Online (Sandbox Code Playgroud)
您可能应该使用相同的互斥锁保护该访问权限,否则您可能会以"半状态"读取它(当另一个线程只是更新变量的一部分时).
而且,我不得不说,我不确定在这里明智地使用线程.互斥体的使用可能会淹没一个声明,就像A[ia++] = ai绝大多数时间用于锁定和解锁互斥锁一样.在锁定期间处理的代码更加实用的情况下,它们通常更有用.
你可能会发现一个非线程的变种会将这个变为水中(但是,当然,不要接受我的话 - 我的主要优化口号是"测量,不要猜测").
| 归档时间: |
|
| 查看次数: |
221 次 |
| 最近记录: |