这个多线程代码(pthreads - c)的输出应该是什么?

2eafrhcq  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(94)
#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万吗?
请解释一下我在概念上哪里错了?

tzdcorbm

tzdcorbm1#

代码根据5.1.2.4多线程执行和数据竞争,p25调用未定义的行为:
如果一个程序在不同的线程中包含两个冲突的操作,其中至少一个不是原子的,并且两者都没有在另一个之前发生,则该程序的执行包含数据竞争。任何这样的数据竞争都会导致未定义的行为。
正如在注解中已经指出的,d++不是一个 * 原子 * 操作,因为它至少涉及三个独立的步骤:从内存中读取值,递增变量,然后将新值存储到内存中。根据5.1.2.4p25,尝试从多个线程执行这一系列操作会导致竞争条件,并调用未定义的行为。
因此,没有“正确”的结果。

相关问题