sowrdking
sowrdking

Reputation: 239

global variable won't change in other thread in c

I have a global variable in c program, and my environment is Linux. When I change my global var in main thread, I see the change is right but nothing happen in other thread. My global is declared in .h file and the .c is the same file name. But if I change the global in one other thread, and the other threads will change. I have print the memory of the global var, and it's the same in main and other threads. Below is my code sample.

int pause_flag;

int initThread() {
    int err;

    err = pthread_create(&user_request_thread, NULL, (void *)&user_request_handler, NULL);
    if (err != 0)
        return(EXIT_FAILURE);

    printLog("Agent-Less service", "start...");

    closelog();
    pthread_join(user_request_thread, NULL);    
    pthread_detach(user_request_thread);

    return(EXIT_SUCCESS);
}

int pause() { 
    setPauseFlag(1);

    return EXIT_SUCCESS;
}

void user_request_handler(void *arg) {
    while (1) {
        printf("pause_flag %d\n", getPauseFlag());
        sleep(5);
    }
    pthread_exit(0);
}

void setPauseFlag(int value) {
    pthread_mutex_lock(&pause_lock);
    pause_flag = value;
    pthread_mutex_unlock(&pause_lock);
}

int getPauseFlag() {
    int temp;

    pthread_mutex_lock(&pause_lock);
    temp = pause_flag;
    pthread_mutex_unlock(&pause_lock);

    return temp;
}

Upvotes: 2

Views: 2743

Answers (1)

user3386109
user3386109

Reputation: 34829

On multi-core systems, even volatile is not enough to guarantee synchronization between threads. volatile will force a write to the underlying hardware, which could be a hardware register in some peripheral chip, or just a location in DRAM. But it won't necessarily update the variable on a different processor core, if that other core has a cached copy of the variable. In other words, volatile doesn't force cache coherency across multiple processor cores.

To force an update to a variable that is guaranteed visible in all threads on all cores, you need to use one of the kernel's synchronization mechanisms, e.g. a semaphore.

http://en.wikipedia.org/wiki/Memory_barrier

See also the link provided by pat in the comments.

The code for the get function should look like this

int getPauseFlag()
{
    int temp;

    pthread_mutex_lock(&pause_lock);
    temp = pause_flag;
    pthread_mutex_unlock(&pause_lock);

    return temp;
}

Upvotes: 4

Related Questions