Проблема в том, что вы не обновляете globalindex
сразу после инициализации localindexup
и localindexdown
для каждого потока, т. Е. В первом критическом разделе.
В вашем коде есть три критических раздела.
Представьте, что thread0
запускает первый критический раздел, затем thread1
выгружает thread0
сразу после того, как thread0
снимает блокировку первого критического раздела. Но поскольку вы устанавливаете globalindex
в localindexdown
в третьем критическом разделе, а не в первом, thread1
по-прежнему будет видеть globalindex=0
, точно так же как thread0
, поэтому он будет пересчитывать ту же сумму, что и thread0
. Вы должны поместить globalindex = localindexdown;
в первый критический раздел.
На самом деле вообще нет необходимости в третьем критическом разделе:
pthread_mutex_lock(&mutex);
int localindexup = globalindex + eachThreadHandles;
int localindexdown = globalindex;
int localsum=0;
long localparam = (long)param;
if(y != leftoverHandle ){
localindexup++;
y++;
}
globalindex = localindexdown; //<--- MOVED HERE
pthread_mutex_unlock(&mutex);
И, забыв мой комментарий о цикле, я допустил ошибку:while(localindexdown<localindexup)
можно безопасно прервать, потому что переменные не являются общими для потоков. Вы можете просто немного повысить производительность, сократив область мьютекса, включив в нее только общие данные:
while(localindexdown<localindexup)
{
pthread_mutex_lock(&mutex);
sum = sum+array[localindexdown];
pthread_mutex_unlock(&mutex); //<--- MOVED HERE
localsum = localsum+array[localindexdown];
localindexdown++;
}