2015-05-25 3 views
0
#include <iostream> 
#include <thread> 
#include <mutex> 

std::mutex mx; 
void some_function() 
{ 
    while(1) 
    { 
     std::lock_guard<std::mutex> mx_guard(mx); 
     std::cout << "some_function()\n"; 
    } 
} 

void some_other_function() 
{ 
    while(1) 
    { 
     std::lock_guard<std::mutex> mx_guard(mx); 
     std::cout << "some_other_function\n"; 
    } 
} 

int main() 
{ 
    std::thread t1(some_function); 
    std::thread t2 = std::move(t1); //t2 will be joined 

    t1 = std::thread(some_other_function); 

    if(t2.joinable()) 
    { 
     std::cout << "t2 is joinable()\n"; 
     t2.join(); //calling join for t1 
    } 
    if(t1.joinable()) 
    { 
     std::cout << "t1 is joinable()\n"; 
     t1.join(); 
    } 
    return 0; 
} 

У меня есть другой выход для этой программы на windows и linux. В окнах с использованием visual studio 13 компилятора я получаю следующий вывод.C++ 11 Поведение различного поведения на linux и windows

some_function() 
some_other_function 
some_function() 
some_other_function 
some_function() 
some_other_function 
some_function() 
some_other_function 
some_function() 
some_other_function 
some_function() 
some_other_function 

Но на Linux с помощью GCC на выходе отличается

some_function() 
some_function() 
some_function() 
some_function() 
some_function() 
some_function() 
some_function() 
some_other_function 
some_other_function 
some_other_function 
some_other_function 
some_other_function 
some_other_function 
some_other_function 

На окнах два потока печатают один за другим, но на Linux это не то же самое поведение. Использование мьютекса на linux не синхронизируется. Как синхронизировать на linux?

+0

Сколько у вас ЦП в вашей системе? Заказ выполнения между потоками не гарантируется. – myaut

+3

«Использование мьютекса на Linux не синхронизируется» - вы не можете заключить, что из этого вывода. Вообще. – Mat

+0

Что вы * точно * планируете делать? Мы не можем вам помочь, если все, что вы предоставляете, является шаблоном. –

ответ

3

A mutex - это просто блокировка для предотвращения одновременного доступа к общему ресурсу, в данном случае std :: cout. И в обоих случаях только один поток записывает std::cout за раз. Хотя возможно, что при некоторых обстоятельствах разблокировка мьютекса может привести к пробуждению другой задачи, это не то, что вам следует ожидать или полагаться, если вы не отвечаете за код OS/scheduler самостоятельно.

Мьютекс : Ограничение доступа к std :: cout: Если вы используете тот же код без блокировки, вы, вероятно, увидите искаженный/смешанный вывод на одной ОС или другой.

Тот факт, что вы видите что-то подобное в Visual Studio, является чисто случайным и не гарантируется, а тот факт, что вы видите что-то еще под Linux, скорее всего, будет отличаться от того, как выполняется IO, чем потоки работают.

Я размышляю о том, что вы на самом деле пытаетесь сделать здесь, но я подозреваю, что вы хотите condition_variable и notify_one. Тем не менее, вы снова не должны предполагать, что он будет круглым.

Кроме того, joinable() проверяет, является ли резьба запущены, join() ждет их остановить, но так как ваши потоки находятся в постоянном цикле, первый вызов join() будет висеть вечно.

--- EDIT ---

Когда я запускаю свой код под Visual Studio 2015 с/O2, я получаю тот же результат, как вы сообщаете для Linux.

+0

спасибо за разъяснение. – sanjay

+0

если у нас есть бесконечные петли в двух или более потоках, то как присоединиться к ним? или мы должны использовать некоторый флаг и основываться на некоторой переменной состояния, которую мы должны продолжить? – sanjay

+0

Ну, 'join' означает« wait for exit », если вы изменили' while (1) 'to' for (size_t i = 0; i <10000; ++ i) 'они в конце концов закончатся и' join() ' преуспеет.Стандарт C++ не дает возможности явно отменить поток. Вы можете использовать 'std :: shared_future ' (http://en.cppreference.com/w/cpp/thread/shared_future) как способ уведомлять потоки, которые вы хотите остановить. См. Http://pastebin.com/uHVWSwyN – kfsone

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