2016-12-21 10 views
2

Я новичок в многопоточном программировании. У меня есть простая программа тестирования:Разница во времени и времени разблокировки Mutex

#include <mutex> 
#include <thread> 
#include <iostream> 
int main(){ 
    std::mutex mtx; 
    std::thread t1([&](){ 
     while (true){ 
      mtx.lock(); 
      std::cout << 1 << "Hello" << "\n"; 
      mtx.unlock(); 
     } 
    }); 
    std::thread t2([&](){ 
     while (true){ 
      mtx.lock(); 
      std::cout << 2 << "Hello" << "\n"; 
      mtx.unlock(); 
     } 
    }); 
    t1.join(); 
    t2.join(); 
} 

Это довольно простая программа, и она печатает «1Hello» и «2Hello» в случайном порядке, который предполагает, что мьютекс разблокируется один, а затем приобретен другой и выполненный в некотором случайном порядке.

Указано ли поведение в стандартном, то есть будет ли реализация гарантировать, что она не будет придерживаться t1? А если нет, то как этого избежать?

+0

Не нужно * предполагать *, что 't1' разблокирует мьютексы. Просто прочитайте код! Кроме того, кажется, вам нужно прочитать современную * упреждающую * многозадачность и то, как она работает. –

+0

Я не думаю, что стандарт гарантирует это, но на практике, да, оба будут выполнены. – MikeMB

+0

Вы можете уточнить ТОЧНО, каков ваш вопрос (может быть, добавить подсказку), потому что я просто не получаю :( вопрос в широком ответе здесь + Я думаю, после того, как вам нужно прочитать краткое руководство по многопоточным \ расам -condition \ dead-lock \ live-lock и т. д. вы сможете ответить на ваши вопросы таким типам (было ли это сделано :)) – LordTitiKaka

ответ

3

Не должно быть гарантии того, кто будет работать. Если вы можете установить приоритет одного потока выше другого, тогда вы можете гарантировать с этим кодом, что будет работать только поток с самым высоким приоритетом.

В чем проблема? Проблема в том, что этот код использует многопоточность наихудшим образом. Это достижение, а не плохое, потому что это упражнение. Он просит потоки работать непрерывно, он блокируется при выполнении длинных действий и только разблокируется для следующего цикла, поэтому на самом деле нет параллелизма, а только битвы за мьютекс.

Как это можно решить? Пусть потоки выполняют какое-то фоновое действие, а затем останавливают или позволяют потокам ждать состояния, по крайней мере, позволяют потокам спящих раз в то время И пусть потоки выполняются как можно более независимыми, а не блокируют других, делая потенциально длительные действия.


Edit (небольшое уточнение): в то время как этот код использует многопоточность в наихудшем смысле, это хороший и чистый пример того, как это сделать.

+0

Да, что программа с ее полным кодом, являющимся критическим сектором, не должна распараллеливаться ... Так что, но как насчет более общего случая, что несколько потоков выполняют одну и ту же работу (скажем, сон) и мало охраняются мьютексом, это на самом деле то же самое (не так ли?), только изменило вероятность того, что ОС не будет придерживаться одного. – YiFei

+0

Планировщик дает время тем потокам, которые являются активными, поэтому, если достаточное количество потоков сходит (дождитесь тайм-аута или для некоторого состояния), тогда проблем не должно быть. Когда больше потоков активнее в течение более длительного времени, планировщик может провести справедливое планирование и назначить временные срезы для разных потоков (на одноядерном многоядерном процессоре немного сложнее), но это обрабатывается ОС, а не C++. – stefaanv

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