【问题标题】:Do all threads have the same global variable?所有线程都具有相同的全局变量吗?
【发布时间】:2021-08-06 01:45:03
【问题描述】:

在尝试使用信号量实现线程同步问题时,我遇到了一个一般性问题。我不想涉及太多(不相关的)细节,所以我将给出我认为对澄清我的问题很重要的代码。

sem_t *mysema;
violatile int counter;

struct my_info{
    pthread_t t;
    int id;
};

void *barrier (void *arg){
    struct my_info *a = arg;
    arg->id = thrid;
    
    while(counter >0){
        do_work(&mysem[thrid])

        sem_wait(&mysema[third])
        
        display_my_work(arg);
        counter--;
        sem_post(&mysema[thrid+1])
    }   
    return NULL;            
}           

int main(int argc, char *argv[]){

    int N = atoi(argv[1]);
    mysema = mallon(N*(*mysema));
    counter = 50;
    /*semaphore intialisations */
    for(i=0; i<M; i++){
        sem_init(&mysema[i],0,0);
    }
    
    for(i=0; i<M; i++){
        mysema[i].id = i;
    }
    
    for(i=0; i<M; i++){
        pthread_create(&mysema.t[i], NULL, barrier, &tinfo[i])
    }   
    /*init wake up the first sempahore */
    sem_post(&mysema[0]);   
.
.
.

我们有一个由 M 信号量组成的数组,初始化为 0 ,其中 M 由用户在命令行中定义。
当所有 M 个线程总共进行了 50 次必要的计算时,我知道我已经完成了。
每个线程自己阻塞,直到前一个线程“sem_post”它。第一个线程将被 init 唤醒。
我的问题是当'''counter = 0'''时线程是否会停止。 他们都看到同一个变量 - 计数器吗?(它是一个全局变量,在 main 中初始化)。
如果线程为零,则第一次生成 ```counter = 49''' 所有其他线程(线程 1、2、...M-1)都看到了吗?

【问题讨论】:

标签: c multithreading synchronization pthreads semaphore


【解决方案1】:

这些是不同的问题:

[线程] 是否都看到同一个变量 - 计数器?(它是一个全局变量,在 main 中初始化)。

如果线程为零,则第一次 ```counter = 49''' 会执行所有其他线程(线程 1、2、...M-1)看到吗?

第一个相当简单:是的。在文件范围内声明且没有存储类说明符_Thread_local 的对象是单个对象,其存储持续时间是程序的整个运行。只要该对象的标识符在范围内且可见,它就标识同一个对象,而不管哪个线程正在访问它。

第二个问题的答案更复杂。在多线程程序中存在数据竞争的可能性,并且包含数据竞争的程序的行为是未定义的。 volatile 限定符不能防止这些;相反,您需要对每个共享变量的所有访问进行适当的同步,包括读取和写入。这可以由信号量或更常见的互斥体提供,以及其他可能性。

您的代码减少counter 可能受到充分保护,但我怀疑不会,因为线程使用不同的信号量。如果这允许多个不同的线程执行 ...

        display_my_work(arg);
        counter--;

... 同时行,那么你就有了数据竞争。但是,即使您的保护足够,在while 条件下读取counter 显然没有正确同步,并且您肯定存在数据竞争。

数据竞争带来的未定义行为的常见表现之一是线程看不到彼此的更新,因此您的程序的未定义行为通常不仅意味着线程 1 .. . M-1 可能看不到线程 0 对counter 的更新,它也特别使得这种失败的可能性比较大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多