2016-06-06 2 views
1

Я сделал тест, но не знаю порядок выполнения потоков.
C++ многопоточность: порядок выполнения

Вот мой код:

void func1() 
{ 
    std::this_thread::sleep_for(std::chrono::milliseconds(4000)); 
    std::cout<<"func1"<<std::endl; 
} 

void func2() 
{ 
    std::this_thread::sleep_for(std::chrono::milliseconds(4000)); 
    std::cout<<"func2"<<std::endl; 
} 
int main() 
{ 
    std::thread t(func1); 
    std::thread t2(func2); 

    t.join(); 
    t2.join(); 
    std::this_thread::sleep_for(std::chrono::milliseconds(8000)); 

    cout << "Hello World" << endl; 

    return 0; 
} 

В этом случае, я получил результат ниже:
ждать в течение 4 сек ---> "func1func2 \ п \ п" показывается --- > wait for sec ---> Отображается «Hello world».

Если изменить порядок кода в main, как показано ниже:

t.join(); 
std::this_thread::sleep_for(std::chrono::milliseconds(8000)); 
t2.join(); 

я могу получить тот же результат, как и выше.

Однако, если я могу изменить его так:

std::this_thread::sleep_for(std::chrono::milliseconds(8000)); 
t.join(); 
t2.join(); 

Результат будет выглядеть так:
ждать в течение 4 сек ---> "func1func2 \ п \ п" показывается ---> ожидание для sec ---> «Привет, мир».
Кажется, что основной поток и t и t2 ожидают в течение 4 секунд одновременно.

Как объяснить все это?

+1

Запуск параллельно - это то, для чего предназначены потоки. Только если вы вызываете 'join', один поток ожидает состояние законченного состояния другого. Таким образом, в последнем случае потоки ожидают 4 секунды, заканчивают, основной поток тем временем ждет 8 секунд, а затем на 'join' не нужно ждать, потому что оба потока завершены, и выводит« Hello World ». –

ответ

0

Без использования блокировок (как правило, семафоров в вашем случае) вы просто не можете предсказать порядок выполнения вашей нити. Только этот планировщик процессов определит это (очень низкий уровень, который помогает вашему процессору переключаться между контекстами).

В вашем первом случае начинается два потока, а после 4 секунд печатается «funcX» (что соответствует их функциям). Основной поток будет ждать потоков для соединения (цель метода соединения), а затем ждать 8 секунд перед печатью «hello world»: метод join заблокирует выполнение основного потока до тех пор, пока потоки не будут выполнены.

В вашем втором случае потоки присоединяются ПОСЛЕ ожидания 8 секунд: фактически главный поток и два других ждут в одно и то же время. Итак, через 4 секунды они печатают свое сообщение, а спустя 4 секунды (главное уже ждало 4 сек.) Появляется «привет мир»!

Надеюсь, это поможет вам понять, что здесь происходит!

+0

ведь есть 3 случая. Можете ли вы объяснить второй? 't.join main.waitfor (8сек) t2.join'? Я думаю, что ваш «второй случай» - это мой «третий случай». – Yves

+0

Случай, указанный в вашем комментарии, будет выполняться следующим образом: – Polux66

+0

(неправильное использование моего kb, извините) У вас возникли трудности с пониманием, так это использование метода join(): этот метод говорит основному ждать потока заканчивать. Однако нить может закончиться до этого. – Polux66

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