In C++, does a data race in one possible scenario render the program's behaviour undefined even if that scenario never gets executed?

huangapple go评论77阅读模式
英文:

In C++, does a data race in one possible scenario render the program's behaviour undefined even if that scenario never gets executed?

问题

以下程序包含数据竞争:

#include <iostream>
#include <thread>
#include <chrono>
#include <string>

using namespace std::chrono_literals;

int sharedVar = 42;

void func(const std::string& threadName) {
    int input;

    while(true) {
        std::cout << "[" << threadName << "]输入一个数字: " << std::endl;
        std::cin >> input;

        if(input == 42) {
            sharedVar++;
        }
        else {
            std::this_thread::sleep_for(1s);
        }
    }
}

int main() {

    std::thread t(func, "线程");
    t.detach();

    func("主程序");
}

如果两个线程在没有同步的情况下访问sharedVar,并且用户没有提供input == 42,根据cppreference的说法,程序的行为是未定义的。

上面的程序是否保证可以正常工作(没有任何未定义的行为),如果用户从未提供input == 42

还是说执行的情景(运行时是否提供42的输入)根本不重要,程序始终是未定义的。

我提出这个问题是因为有时在讨论数据竞争时,讨论会涉及执行的细节,例如在上面的情况下用户是否会在输入中提供42。

编辑:我想要添加我在网上找到的这篇文章,这篇文章似乎与此相关。根据我对这篇文章的理解,提供的输入并不重要。行为将始终是未定义的。

编辑2:基本上,我对此处提到的第2类函数很感兴趣。

英文:

The following program contains a data race:

#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;chrono&gt;
#include &lt;string&gt;

using namespace std::chrono_literals;

int sharedVar = 42;

void func(const std::string&amp; threadName) {
    int input;

    while(true) {
        std::cout&lt;&lt;&quot;[&quot;&lt;&lt;threadName&lt;&lt;&quot;]Enter a number: &quot;&lt;&lt;std::endl;
        std::cin&gt;&gt;input;

        if(input == 42) {
            sharedVar++;
        }
        else {
            std::this_thread::sleep_for(1s);
        }
    }
}


int main() {

    std::thread t(func, &quot;thread&quot;);
    t.detach();

    func(&quot;main&quot;);
}

Both threads are accessing sharedVar without any synchronisation if they are given input == 42 from the user.

As per cppreference,

> If a data race occurs, the behavior of the program is undefined.

Is the above program guaranteed to work fine (without any undefined behaviour) if input == 42 is never provided?

or

Does the scenario of execution (whether 42 is provided in the input or not at runtime) not matter at all and the program is always undefined.

I ask this question because sometimes, during the discussion on data races, the discussion goes into the details of execution; e.g. in the above case whether the user will provide 42 or not in the input.

Edit
Just wanted to add this article I found online which seemed relevant. As per my understanding of this, the input which is given does not matter. The behaviour will remain undefined.

Edit 2
Basically the type 2 functions mentioned here is what I'm interested in.

答案1

得分: 1

以下是翻译好的部分:

"The following program contains a data race"(以下程序存在数据竞争)

"For some input values"(对于某些输入值)

"particularly both threads need to see input of 42, not just one thread"(特别是两个线程都需要看到输入为42,而不仅仅是一个线程)

"A data race is a property of an execution, not of the program in the abstract. From [intro.races#21]"(数据竞争是执行的属性,而不是抽象程序的属性。来自[intro.races#21])

"If yes, then is the above program guaranteed to work fine (without any undefined behaviour) if input == 42 is never provided?"(如果是的话,那么上述程序是否保证在没有提供input == 42的情况下能够正常工作(没有任何未定义行为)?)

"Yes. It will continue to loop forever prompting for and accepting input."(是的。它将继续无限循环提示输入并接受输入。)

"Aside: I would be wary of supplying functions with reference parameters to std::thread::thread, although in this case it is fine, because you pass a const char[] not a rvalue std::string."(顺便说一下:我会谨慎提供引用参数给std::thread::thread函数,尽管在这种情况下是可以的,因为您传递的是const char[]而不是rvalue std::string。)

英文:

> The following program contains a data race

For some input values, particularly both threads need to see input of 42, not just one thread.

A data race is a property of an execution, not of the program in the abstract. From [intro.races#21]:

> The execution of a program contains a data race if

> If yes, then is the above program guaranteed to work fine (without any undefined behaviour) if input == 42 is never provided?

Yes. It will continue to loop forever prompting for and accepting input.

Aside: I would be wary of supplying functions with reference parameters to std::thread::thread, although in this case it is fine, because you pass a const char[] not a rvalue std::string.

huangapple
  • 本文由 发表于 2023年4月4日 14:42:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定