c++ 对全局变量所做的更改反映在另一个线程中是否正常(可能性)?

wz3gfoph  于 2023-02-10  发布在  其他
关注(0)|答案(1)|浏览(136)
#include <string>
#include <iostream>
#include <thread>
#include <iostream>
#include <unistd.h>
int x = 0;

void foo()
{
    std::cout << "x foo(): " << x;
    sleep(9); // this is to simulate context switch
    
    // Is this the expected (default) behavior?
    std::cout << "\nx foo() after sleep (after context switch): " << x;
}

void foo2()
{
    x = x + 1;
}

int main()
{
    std::thread t1(foo);
    sleep(5); // simulate posible context switch
    std::thread t2(foo2);
    t1.join();
    t2.join();
}

一个可能的输出(有时会给出其他输出,但与问题无关):

x foo(): 0
x foo() after sleep (after context switch): 1 // change made by another thread

这是预期的(默认)行为吗?
也就是说,对于一个线程来说,每次它在它的线程中读取其他线程时,它都能看到**其他线程所做的全局变量更改
如果我进行这些更改:

void foo()
{
    int count = x;
    std::cout << "count foo(): " << count;
    sleep(9); // this is to simulate context switch
    
    // Is this the expected (default) behavior?
    std::cout << "\nx count() after sleep (after context switch): " << count;
}

可能输出:

count foo(): 0
x foo() after sleep (after context switch): 0

变量在上下文切换中保留了它们的值,因为我使用了另一个变量。
我知道我必须使用同步,但是,

对全局变量所做的更改反映在另一个线程中是否正常(可能性)?

pjngdqdw

pjngdqdw1#

有一个thread_local keyword (since C++11),您可以使用它使每个线程都有自己的“全局”变量。
修改样本:

#include <string>
#include <iostream>
#include <thread>
#include <iostream>
#ifdef _WIN32
#include <Windows.h>
#define sleep Sleep
#else
#include <unistd.h>
#endif

thread_local int x = 0;

void foo()
{
    std::cout << "x foo(): " << x << std::endl;
    sleep(2); // this is to simulate context switch

    // Is this the expected (default) behavior?
    std::cout << "x foo() after sleep (after context switch): " << x << std::endl;
}

void foo2()
{
    std::cout << "x foo2(): " << x << std::endl;
    x = x + 1;
    std::cout << "x foo2(): " << x << std::endl;
}

int main()
{
    std::thread t1(foo);
    sleep(1); // simulate posible context switch
    std::thread t2(foo2);
    t1.join();
    t2.join();
    std::cout << "Main thread: " << x << std::endl;
}

所以,为了回答你的问题,你所观察到的行为只是C的默认行为,和任何默认行为一样,C允许你改变它。

相关问题