#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define max_thread 5
int d = 0;
pthread_t thread_id[max_thread];
//the thread function definition
static void* thread_func(void* data){
for(int i = 0; i < 100000; i++){
d++;
}
return NULL;
}
int main(){
int rc, i, n;
n = 5;
//creating n=5 threads
for(i = 0; i < 5; i++){
rc = pthread_create(&thread_id[i], NULL, thread_func, NULL);
if(rc){
printf("\n ERROR %d \n", rc);
exit(1);
}
}
//waiting for the threads to finish execution
for(i = 0; i < 5; i++){
pthread_join(thread_id[i], NULL);
}
//printing value of global variable d
printf("counter = %d\n", d);
return 0;
}
这段代码的输出应该是什么?当我执行它时,它给出了一些任意值(<<500000)。
我理解线程的临界区(在本例中-更新d的值)在线程中执行时应该被锁定。但是如果我把它看作一个整体,说变量d递增了5,00,000倍,这是错的吗?如果我把150万次加起来,不管加的顺序如何,答案不应该是50万吗?
请解释一下我在概念上哪里错了?
1条答案
按热度按时间tzdcorbm1#
代码根据5.1.2.4多线程执行和数据竞争,p25调用未定义的行为:
如果一个程序在不同的线程中包含两个冲突的操作,其中至少一个不是原子的,并且两者都没有在另一个之前发生,则该程序的执行包含数据竞争。任何这样的数据竞争都会导致未定义的行为。
正如在注解中已经指出的,
d++
不是一个 * 原子 * 操作,因为它至少涉及三个独立的步骤:从内存中读取值,递增变量,然后将新值存储到内存中。根据5.1.2.4p25,尝试从多个线程执行这一系列操作会导致竞争条件,并调用未定义的行为。因此,没有“正确”的结果。