0

I change a global variable in one thread, and the change will not take effect in another thread if I do not print it

Here's the code:

pthread_t thread_test[2];
bool test=true;

void* test1(void*)
{
    while(1)
    {
        //printf("test: %d\n",test);
        if(test)
            continue;
    
        printf("test test test\n");
        usleep(500000);
    }
}

void* test2(void*)
{
    int i=0;
    while(i<5)
    {
        printf("i: %d\n",i++);
        sleep(1);
    }
    test=false;
    return NULL;
}

int main()
{
    pthread_create(&thread_test[0], NULL, &test1, (void *)NULL);
    pthread_create(&thread_test[1], NULL, &test2, (void *)NULL);
    pthread_join(thread_test[0],NULL);

    return 0;
}

If the line printf("test: %d\n",test); is commented out.Then the change of test in test2 will not take effect in test1.

The run results are shown in below: enter image description here

if don't commented out it: enter image description here

This has troubled me for a long time. Wish someone please answer it.

DeGrey
  • 1
  • 1

1 Answers1

-1

Compiler is probably optimizing out the "while(1)" loop content, assuming global test is always true

Got the same results with qnx compiler 'release' setup: -g0 -O3

Got "test test test" (test turned false) with 'debug' setup: -O0 -g3 -ggdb

p.s.

volatile bool test=true;

with 'release' setup also does the trick (despite what others wrote above)

enter image description here

  • 1
    It may well be that the compiler is performing an optimization such as you describe, but that misses the key point here: the program contains data races involving shared variable `test`, and therefore its behavior is undefined. How that undefinedness manifests is largely moot. And presumably the OP is looking for a solution, which could be to apply appropriate synchronization, for example, or to use an atomic object instead of a non-atomic one. – John Bollinger Feb 08 '23 at 14:37
  • `volatile` does not work. See [**Does "volatile" guarantee anything at all in portable C code for multi-core systems?**](https://stackoverflow.com/questions/58695320/does-volatile-guarantee-anything-at-all-in-portable-c-code-for-multi-core-syst), [**Volatile: Almost Useless for Multi-Threaded Programming**](https://web.archive.org/web/20120210232850/http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/) – Andrew Henle Feb 08 '23 at 15:09
  • Along with [**Should volatile Acquire Atomicity and Thread Visibility Semantics?**](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html) Note that's a proposal to **add** atomicity and thread visibility semantics to `volatile`, which means it doesn't have those semantics that are **necessary** for multithreaded use, so `volatile` **is not sufficient for multithreaded programming**. – Andrew Henle Feb 08 '23 at 15:11
  • I was not assuming to read OPs hidden intentions, just answer the question. Also, volatile worked on my qnx - I make it a habbit not to argue with facts – user21158246 Feb 08 '23 at 15:19
  • @user21158246 You're confusing "I didn't observe it to fail" with "worked". – Andrew Henle Feb 08 '23 at 16:22
  • Andrew dont project your issues onto me – user21158246 Feb 08 '23 at 16:54
  • @user21158246 The only issue here is this answer is **wrong**. I've provided multiple references as to *why* it's wrong. Whether or not you want to learn from this or stick to your "volatile worked" fantasy without understanding why it did nothing more than hide the real problem *this time*, that's up to you. – Andrew Henle Feb 09 '23 at 18:42
  • Read OPs question. Nothing mentioned about atomic access or threads sync. You're simply taking an advantage of me being a new user to enforce your (-1)..that is a shame.. https://en.cppreference.com/w/cpp/language/cv : volatile object - an object whose type is volatile-qualified, ... Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be optimized out or reordered ..) – user21158246 Feb 11 '23 at 10:40