我有一个非常简单的多线程程序,在这个程序中,我阅读一组数字,并最终将它们添加到全局sum
中。我在每个线程中使用local_sum
变量,然后将其添加到全局sum
中。代码在最后给出。
问题是-我是否需要锁定thread_runner
函数中的这行代码?
sum += local_sum;
我很确定我确实需要锁定它,但是程序总是给出正确的结果。如果我确实需要锁定,我如何证明这个实现是错误的?
注意:我只对互斥锁作为同步原语感兴趣。另外请忽略我没有检查返回值。
代码:
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void *thread_runner(void *index);
// pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
long array[100000000];
long sum = 0;
int main() {
/* Insert values in the array */
long i = 0;
for (i = 0; i < 100000000; i++) {
array[i] = i+1;
}
/* Declare thread variables */
pthread_t t1, t2, t3, t4;
int index1 = 0;
int index2 = 25000000;
int index3 = 50000000;
int index4 = 75000000;
/* Create 4 threads */
int rc = pthread_create(&t1, NULL, thread_runner, &index1);
rc = pthread_create(&t2, NULL, thread_runner, &index2);
rc = pthread_create(&t3, NULL, thread_runner, &index3);
rc = pthread_create(&t4, NULL, thread_runner, &index4);
/* Wait for threads to complete */
rc = pthread_join(t1, NULL);
rc = pthread_join(t2, NULL);
rc = pthread_join(t3, NULL);
rc = pthread_join(t4, NULL);
printf("Sum: %ld\n", sum);
return 0;
}
void *thread_runner(void *index) {
int i = 0;
int i_index = *((int*)index);
long local_sum = 0;
for (i = i_index; i < i_index+25000000; i++) {
local_sum += array[i];
}
// Do i need to lock the following statement ?
sum += local_sum;
}
1条答案
按热度按时间fdbelqdn1#
我如何证明这个实现是错误?
你指向
sum += local_sum
行,然后说,“看!线程访问相同的共享变量,没有任何锁定,也没有任何其他形式的同步,”然后你指向语言规范中的部分,或者你指向some other suitable authority,它说“...未定义的行为”。数据竞赛之所以糟糕,是因为它们是“不可预测的”。你不能依赖于一个包含数据竞赛的程序来给予正确的答案,也不能依赖于它来给出“错误的”答案。你不能依赖于测试来发现数据竞赛。