2012-04-23 3 views
1

Я примеряю некоторые примеры из C++11 threads Я вижу некоторые неожиданные результаты. С помощью следующего кодаstd :: thread and std :: endl no expected output

#include <iostream> 
#include <thread> 

void hello() { 
    std::cout << "Hello concurrent world " << std::endl; 
} 
void do_something() { 
    std::cout << "[background_task] --> [ do_something ]" << std::endl; 
} 
void do_something_else() { 
    std::cout << "[background_task] --> [ do_something_else ]" << std::endl; 
} 
class background_task { 
public: 
    void operator()() const  {  
     do_something(); 
     do_something_else(); 
    } 
}; 

int main (int argc, char **argv) { 
    std::thread t(hello); 
    background_task bt; 
    std::thread fn_obj_th(bt); 
    t.join(); 
    fn_obj_th.join(); 
} 

выхода следующего

Hello concurrent world [background_task] --> [ do_something ] 

[background_task] --> [ do_something_else ] 
Press any key to continue . . . 

Если я заменяю std::cout << "Hello concurrent world " << std::endl; с std::cout << "Hello concurrent world \n";

Результат

Hello concurrent world 
[background_task] --> [ do_something ] 
[background_task] --> [ do_something_else ] 

Почему в случае с std::endl я не получаю ожидаемого выхода.

+2

Какой выход ожидался? – jalf

ответ

8

Это:

std::cout << "Hello concurrent world " << std::endl; 

два отдельных выходы. В то время как std::cout является потокобезопасным, это не означает, что две отдельные его вызовы гарантированно будут атомарными. Один выход является атомарным, но не двумя.

Если вы хотите, чтобы определенное выражение гарантировало, что оно будет атомарным, вы должны добавить свои собственные примитивы синхронизации поверх std::cout.

+0

Вы говорите, что std :: cout << «Привет, параллельный мир» выполняется сначала, а затем происходит переключение потоков и std :: endl; происходит после этого, не могли бы вы объяснить – Avinash

+5

@ Авинаш: Да, это то, что я говорю (более или менее). Вероятно, вам следует исследовать концепцию «атомных операций» при поточной передаче, прежде чем продолжать использовать потоки в вашей программе. –

+0

@Avinash Попробуйте с чем-то другим, кроме символа пробела. –

Смежные вопросы