2016-07-26 4 views
1

Я подумываю о некотором примитиве синхронизации, но я не знаю, как называется эта синхронизация или что-то вроде этого будет работать.Параллельный код без ожидания

Таким образом, существует одна переменная (логическая), которая в основном сигнализирует, если один поток все еще работает над блоком памяти или нет. В начале bool устанавливается в false, то есть рабочий поток не работает на вашем блоке памяти. Теперь основной поток дает рабочему потоку «todo-list», описывая, как он должен работать над этим блоком памяти. После этого он изменяет состояние логического на true, так что рабочий поток знает, что теперь ему разрешено выполнять свою работу. Основной поток теперь может продолжать свою собственную работу и проверять в определенных местах, если рабочий поток теперь работает, например. если логическое значение снова установлено на false. Если он равен true, основной поток просто продолжает свою собственную работу и не ждет рабочего потока. Если логическое значение false, основной поток знает рабочий рабочий процесс и начинает обработку блока памяти.

Таким образом, логическое значение просто переносит владение над блоком памяти между двумя потоками. Если один поток в настоящее время не имеет права собственности на эту память, он просто продолжает свою собственную работу и неоднократно проверяет, имеет ли он теперь право собственности. Таким образом, ни один из потоков не ждет друг друга и может продолжить свою работу.

Как это называется и как осуществляется такое поведение?

EDIT: В основном это мьютексы. Но вместо ожидания разблокировки мьютекса он продолжает/пропускает критический код.

+0

Это может быть хорошим примером для 'std :: future' и/или' std :: packaged_task'. – amuttsch

+0

Выполнение работы при периодической проверке некоторых внешних событий называется «опрос». Он может быть реализован с помощью атомной переменной. Обычно это не очень хорошая идея. –

+0

Можете ли вы объяснить, почему? –

ответ

1

EDIT: В основном это мьютексы. Но вместо того, чтобы ожидать, что мьютекс будет удален до , он продолжает/пропускает критический код.

Это еще мьютекс, только с методами «попробуйте».

в стандартном C++, мы говорим о std::mutex::try_lock, который пытается заблокировать мьютекс, если он не возвращает ложь и движется по

class unlocker{ 
std::mutex& m_Parent; 

public : 

unlocker(std::mutex& parent) : m_Parent(parent){} 
~unlocker() {m_Parent.unlock(); } 

}; 

std::mutex mtx; 
if (mtx.try_lock()){ 
    unlocker unlock(mtx); // no, you can't use std::lock_guard/unique_lock here 
    //success, mtx is free 
} else{ 
    // do something else 
} 

на коде Native ОС у вас есть аналогичные функции в зависимости от операционной вы находитесь на, как pthread_mutex_trylock на Unix и TryEnterCriticalSection на Windows. Разумеется, стандартные мьютекс, вероятно, используют эти функции за кулисами

+0

Действительно ли это действительный подход? Мне нужно спросить - в параллельном программировании apporaches, которые кажутся простыми, чаще всего ошибочны. –

+0

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

+0

Проблема с 'try_lock' в том, что она ненадежна. Mutex хорошо работает для защиты ресурсов от одновременного доступа, но он довольно жутко работает в сигнализации. В библиотеке потоков C++, если вы хотите сигнализировать, вы, вероятно, хотите либо будущее (для одноразовых сигналов), либо condition_variable (для многоразовых сигналов). – ComicSansMS

0

Что вы будете делать, если основная тема закончится?

Предположим, что вы продолжаете проверять, и вы продолжаете читать true. В конце концов вы достигнете точки, где основной поток не может продолжаться без результата рабочего потока. Поскольку у вас больше нет работы, осталось только одно: теперь нужно постоянно проверять значение флага, тратя ресурсы ЦП, которые другие потоки могут использовать для полезной работы.

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

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

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

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