-1

I have a general question that occured to me while trying to implement a thread sychronization problem with sempaphores. I do not want to get into much (unrelated) detail so I am going to give the code that I think is important to clarify my question.

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]);   
.
.
.

We have an array made of M semaphores intialised in 0 , where M is defined in command line by the user.
I know I am done when all M threads in total have done some necessary computations 50 times.
Each thread blocks itself, until the previous thread "sem_post's" it. The very first thread will be waken up by init.
My question is whether the threads will stop when '''counter = 0 '''. Do they all see the same variable - counter? (It is a global one, initialised in the main).
If thread zero , makes the very first time ```counter = 49''' do all the other threads( thread 1, 2, ...M-1) see that ?

tonythestark
  • 519
  • 4
  • 15

1 Answers1

0

These are different questions:

Do [the threads] all see the same variable - counter? (It is a global one, initialised in the main).

If thread zero , makes the very first time ```counter = 49''' do all the other threads( thread 1, 2, ...M-1) see that ?

The first is fairly simple: yes. An object declared at file scope and without storage class specifier _Thread_local is a single object whose storage duration is the entire run of the program. Wherever that object's identifier is in-scope and visible, it identifies the same object regardless of which thread is accessing it.

The answer to the second question is more complicated. In a multi-threaded program there is the potential for data races, and the behavior of a program containing a data race is undefined. The volatile qualifier does not protect against these; instead, you need proper synchronization for all accesses to each shared variable, both reads and writes. This can be provided by a semaphore or more often a mutex, among other possibilities.

Your code's decrement of counter may be adequately protected, but I suspect not, on account of the threads using different semaphores. If this allows for multiple different threads to execute the ...

        display_my_work(arg);
        counter--;

... lines at the same time then you have a data race. Even if your protection is adequate there, however, the read of counter in the while condition clearly is not properly synchronized, and you definitely have a data race there.

One of the common manifestations of the undefined behavior brought on by data races is that threads do not see each others' updates, so not only does your program's undefined behavior generally mean that threads 1 ... M-1 may not see thread 0's update of counter, it also specifically makes such a failure comparatively probable.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157