2

Let's consider the following code:

#include <iostream>
#include <thread>
int main()
{
    std::thread t1([](){
        int a;
        std::cin >> a;
        std::cout << "T1: " << a << std::endl;
    });
    std::thread t2([](){
        int a;
        std::cin >> a;
        std::cout << "T2: " << a << std::endl;
    });


    t1.join();
    t2.join();
    return 0;
}

Compiled with: g++ -std=c++14 -pthread main.cpp -o main Run with: ./main < file.txt

file.txt:

1 2

The outputs are different ( I supposed so), for example:

T1: T2: 12

    T1: 1T2: 
2

T1: 12
T2: 0

and so on.

I suppose that code causes undefined behaviour? Am I right? And how to solve/explain situation when two threads try use the same ( ? ) input/output?

Gilgamesz
  • 4,727
  • 3
  • 28
  • 63
  • 3
    The behavior is well-defined. But recall that C++ describes a *non-deterministic* abstract machine. Each one of those outcomes is equally valid. You may observe different outcomes on different runs of the same program. – Igor Tandetnik Feb 21 '16 at 15:54
  • It's undefined in C++03 and earlier (as in, the standard doesn't mention anything about it), but defined and well-behaved in C++11 and later ([see e.g. this old answer](http://stackoverflow.com/a/6374525/440558)). – Some programmer dude Feb 21 '16 at 15:58
  • @IgorTandetnik , it is very interesting what you said ( I mean "C++ describes a non-deterministic abstract machine"). Please tell me more / reference me somewhere. :) – Gilgamesz Feb 21 '16 at 16:00
  • @JoachimPileborg This program is not a valid C++03 program to begin with (observe the use of `std::thread`), so appealing to C++03 is rather pointless. – Igor Tandetnik Feb 21 '16 at 16:02
  • 1
    "**[intro.execution]/1** The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine..." "**[intro.execution]/5** A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input..." – Igor Tandetnik Feb 21 '16 at 16:04

1 Answers1

0

It is safe to access standard input and output streams as long as they are synchronized with C-streams (their default state). However output (and input) might be interleaved if you do not use any means to prevent simultaneous access.

27.4.1/4        [iostream.objects.overview]
Concurrent access to a synchronized standard iostream object’s formatted and unformatted input and output functions or a standard C stream by multiple threads shall not result in a data race. [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. —end note ]

Revolver_Ocelot
  • 8,609
  • 3
  • 30
  • 48