не понимаю результат работы параллельной программы
есть такой импровизированный участок кода
#include <iostream>
#include <vector>
#include <algorithm>
#include <thread>
void print_string(const std::string message)
{
std::cout << message;
}
int main()
{
std::thread t1(print_string, "hello ");
t1.detach();
std::vector<int> nums(2000);
for (int i = 0;i < nums.size();++i) {
nums[i] = rand();
}
sort(nums.begin(), nums.end());
std::cout << "world!\n";
return 0;
}
результаты работы: 1) hello world! -- такой исход мне понятен
не понятны такие исходы: 2) world! 3) world! hello
то есть здесь 2000 элементов инициализировались и отсортировались и еще произошел вывод "world!" быстрее чем вывело "hello "? почему такое происходит?
Ответы (1 шт):
Есть такое понятие, как буфер потока. Пока вы не сделаете cout.flush(); строку 'hello ' - не увидите.
Стандарт :
Concurrent access to a stream object (27.8, 27.9), stream buffer object (27.6), or C Library stream (27.9.2) by multiple threads may result in a data race (1.10) unless otherwise specified (27.4). [ Note: Data races result in undefined behavior (1.10). — end note ]
Concurrent access to a synchronized (27.5.3.4) standard iostream object’s formatted and unformatted input (27.7.2.1) and output (27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]
Перевод :
Одновременный доступ к объекту потока (27.8, 27.9), объекту буфера потока (27.6) или потоку библиотеки C (27.9.2) несколькими потоками может привести к гонке данных (1.10), если не указано иное (27.4). [Примечание: гонки данных приводят к неопределенному поведению (1.10). - конец примечания]
Одновременный доступ к синхронизированным (27.5.3.4) стандартным функциям входного (27.7.2.1) и выходного (27.7.3.1) ввода или вывода (27.7.3.1) стандартного объекта iostream или стандартному потоку C несколькими потоками не должен приводить к гонке данных (1.10). [Примечание: пользователи по-прежнему должны синхронизировать одновременное использование этих объектов и потоков несколькими потоками, если они хотят избежать чередования символов. - конец примечания]
Так работает чётко :
void print_string(const std::string message)
{
std::cout << message;
std::cout.flush();
}