我有一个int array[100]
,我想要5个线程来计算所有数组元素的总和。
每个线程在其专用范围内迭代20个元素,并将总和写入全局sum
变量。
这里需要互斥吗?由于所有线程都从独立的源读取数据,因此不需要同步。
for(i=offset; i<offset+range; i++){
// not used pthread_mutex_lock(&mutex);
sum += array[i];
// not used pthread_mutex_unlock(&mutex);
}
这会导致无法预料的行为,还是OS实际处理了此问题?
在这种情况下,建议不要使用互斥锁吗?我注意到,如果没有这些算法,这些算法的运行速度会大大提高。
最佳答案
是的,您需要同步,因为所有线程都在同时修改sum
。例子如下:
您有4个元素[a1, a2, a3, a4]
和2个线程t1
,t2
和sum
组成的数组。首先,让我们说t1
获得值a1
并将其添加到sum
中。但这不是原子操作,因此他将sum
的当前值(它的值为0)复制到他的本地空间,我们称它为t1_s
,将其添加到a1
,然后编写sum = t1_s
。但同时t2
做同样的事情,他将sum
值(为0,因为t1
尚未完成操作)获得到t2_s
,添加a3
并写入sum
。因此,我们获得了由sum
插入的a3
的a1 + a3
值。这称为数据竞赛。
对此有多种解决方案:
mutex
,但是正如您提到的那样,它可能很慢,因为互斥锁很昂贵,并且所有其他线程都在等待它。 sum_local
,最后使用互斥锁将所有这些总和添加到共享变量sum
中。我想它将更快(但是需要检查)。 但是,正如@gavinb所述,所有这些仅对大量数据有意义。
关于c - pthread互斥锁的必要性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30150903/