以下问题:
我的作业是期望我实施一个多线程排序系统(我不是要求你做我的作业,我已经完成了大部分工作,并且在某个问题上需要帮助)。
我有一个N个双打数组,里面填充了随机数。对于这个数组中的每个索引,都有一个posix线程,它将自己的索引元素永远与下一个索引中的元素进行比较,直到有人告诉它停止。
所以,如果我们有索引5的线程,它将永远将自己与下一个元素进行比较,并且如果它自己的元素大于下一个元素,则交换它们。
我已经实现了整个系统:
//related declarations
#define N 10
double x[N];
int isFinished = 0;
pthread_mutex_t indexMutex[N];
void* compareIndices(void* pindex)
{
int index = *((int*)pindex);
int nextIndex = index + 1;
if(nextIndex >= N)
{
nextIndex -= N;
}
while(isFinished == 0)
{
pthread_mutex_lock(&indexMutex[index]);
pthread_mutex_lock(&indexMutex[nextIndex]);
if(x[index] > x[nextIndex])
{
double temp = x[index];
x[index] = x[nextIndex];
x[nextIndex] = temp;
}
pthread_mutex_unlock(&indexMutex[nextIndex]);
pthread_mutex_unlock(&indexMutex[index]);
}
}
int main()
{
int i;
int indices[N];
pthread_t tid[N];
for(i = 0; i < N-1; i++)
{
pthread_mutex_init(&indexMutex[i], NULL);
}
for(i = 0; i < N-1; i++)
{
indices[i] = i;
pthread_create(&tid[i], NULL, compareIndices, (void*)&indices[i]);
}
return 0;
}
我不认为需要在此处发布我的完整代码,因为这已经足以让您了解这个想法。系统已按预期工作,阵列最终完美排序。
但是,我不太确定我的同步是否正确,就像现在这样。
目前,我为每个索引都有一个互斥锁,以避免典型的多线程问题,如下所示:
线程A获取x [index]和x [nextindex]的值,然后比较,发现x [nextIndex]更小,因此它决定交换。此时另一个线程B获取CPU并在x [nextindex]中移动另一个值。回到线程A线程仍然认为存在不匹配并再次交换,但不是来自x [nextIndex]的原始值,而是来自另一个线程的值。
由于这个原因,我认为为每个索引使用互斥锁可能是有意义的。然而,在完成这个解决方案之后,我想起了哲学问题:
如果所有线程同时获取其x [index]锁定会发生什么情况,并且会立即尝试获取x [nextIndex]?它最有可能最终导致无法解决的死锁,因为所有互斥锁都已被锁定,并且没有任何线程可以继续。
我从未在所有测试中发生这种情况,但可能性存在。但是,我不太清楚我还有什么其他方法可以保证这个安全。
是否有任何建议可以指导我找到合适的解决方案?