Дублирование очереди в TPL

Я изучаю параллельную библиотеку задач для .NET (TPL), я пытаюсь понять, как это работает, я понимаю идею кражи работы, но я не могу понять, почему мы используем дублирующую очередь и как это работает?

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

можешь мне помочь ?


person Farah_online    schedule 21.05.2011    source источник
comment
Что такое «дублирующаяся очередь»? Как вы поняли, что это то, что использует TPL?   -  person svick    schedule 21.05.2011
comment
Я прочитал об этом в этом pdf: google.com/   -  person Farah_online    schedule 21.05.2011
comment
спасибо за ссылку, было интересно почитать.   -  person svick    schedule 22.05.2011
comment
Каков именно ваш вопрос? Вы спрашиваете, как работает дублирующая очередь? Вы спрашиваете, как использовать TPL? Что-то другое?   -  person Gabe    schedule 22.05.2011


Ответы (1)


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

В некотором смысле кажется довольно расточительным блокировать push и pop, когда вы знаете, что только один поток будет использовать эти операции. Но вы ничего не можете с этим поделать, если хотите убедиться, что очередь ведет себя правильно.

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

Таким образом, если вы в конце концов исключите задачу из очереди, вы не запустите ее, потому что знаете, что она уже запущена или даже завершена. Что с очередью? Мы сказали, что хотим убедиться, что удаляем задачу из очереди ровно один раз. Но это больше не требуется: если мы удалим какую-то задачу дважды, это не имеет значения, потому что задача позаботится об этом сама и фактически запустится только один раз.

Но это означает, что мы можем снимать блокировки с pop и push, в результате чего получается дублирующаяся очередь, которая работает быстрее, чем обычная очередь для кражи работы, потому что у нее более слабые требования: мы можем быть уверены, что каждая задача удаляется из нее в минимум один раз.

EDIT: ответы на вопросы:

удалить задачу, взяв ее, можно, но удалить задачу, поместив задачу в очередь!

Извините, это была ошибка, сейчас исправлено. Он хлопает или берет.

случай 3 в примере выдумки на странице 6, не так ли?

да.

Зачем? Я не могу понять эту проблему.

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

какова логическая связь между удалением блокировок из pop и push и дублированием очереди?

Когда вы снимаете блокировки, вы не можете быть полностью уверены, что задача будет удалена ровно один раз. Что может случиться, так это то, что в очереди есть только одна задача, и два разных потока одновременно вызывают take и pop. Поскольку pop не использует блокировки, одна и та же задача удаляется дважды.

person svick    schedule 21.05.2011