Наличие локальной очереди потока со счетчиками

У меня есть четыре потока, которые имеют свою собственную частную очередь и член частного 'int count', всякий раз, когда задача создается из потока программы, она должна быть помещена в очередь потока с минимальным 'int count ' среди нитей.

всякий раз, когда задача помещается в очередь, частный «счетчик int» должен увеличиваться на 1, всякий раз, когда задача выталкивается из очереди, частный «счетчик int» должен уменьшаться на 1

таким образом, 'int count' динамически изменяется в зависимости от операции push, pop, и поток программы отправит задачу в очередь с наименьшим (или первым найденным нулем) счетчиком.

Это основная логика программы.

Я работаю на языке программирования С++ в многопоточной библиотеке Linux, реализующей парадигму многоскоростного синхронного потока данных.

Не могли бы вы дать некоторые идеи кодирования для реализации этой логики. т.е. 1. Инициализация счетчика всех частных очередей = 0

2.counter++ при выполнении задачи,

3.counter-- когда задачи всплывают,

4.Task disptacher видит частный счетчик каждого потока.

5. Отправляет задачи в очередь с минимальным количеством


person aram    schedule 09.01.2013    source источник
comment
Это домашнее задание? Нет проблем, если это так, просто интересно, какой уровень детализации вам нужен?   -  person Caribou    schedule 09.01.2013
comment
@Caribou Мне нужна некоторая логика, например, какие циклы или функции следует использовать для увеличения и уменьшения счетчика, когда некоторые задачи помещаются в очередь или извлекаются из нее.   -  person aram    schedule 09.01.2013
comment
Нужны ли дополнительные исследования и информация для ответа на этот вопрос? Пожалуйста, дайте мне знать   -  person aram    schedule 09.01.2013
comment
просто обдумывая ответ сейчас - есть некоторые тонкости из-за того, что вы хотите сделать...   -  person Caribou    schedule 09.01.2013
comment
да, я задам вопрос еще раз с некоторыми дополнительными исследованиями.   -  person aram    schedule 09.01.2013


Ответы (1)


У меня есть четыре потока, которые имеют свою собственную частную очередь и член private'int *count', всякий раз, когда задача создается из потока программы, она должна быть поставлена ​​в очередь в очередь потока который имеет минимальное значение 'int count' *среди потоков.*

всякий раз, когда задача помещается в очередь, частный 'int count' *должен увеличиваться на 1 всякий раз, когда задача извлекается из очереди*, частный 'int count' должен быть уменьшилось на 1

Итак, по существу ваш программный поток является производителем, а у вас есть 4 потока-потребителя. Используя очередь в каждом потоке, вы минимизируете время, затрачиваемое основным потоком на взаимодействие с потребителями. Примечание. Вам необходимо подумать о том, будут ли ваши потоки голодать или переполняться — т.е. если единственный производитель будет создавать «работу» со скоростью, которая гарантирует 4 потребителя, или если 4 потребителя будут завалены.

наивный подход Таким образом, вам нужно синхронизировать доступ к очереди/приращение, что означает, что вам нужен mutex, чтобы запретить потребителю доступ к чему-либо, в то время как count и queue изменяются. Самый простой способ выполнить синхронизацию - это иметь метод (например, enqueue(Item& item) ), который блокирует mutex внутри него.

C++11: Мьютекс http://en.cppreference.com/w/cpp/thread/mutex

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

C++11: переменные условия: http://en.cppreference.com/w/cpp/thread/condition_variable

таким образом, 'int count' динамически изменяется в зависимости от задач *операция push, pop и программный поток отправит задачу в очередь с наименьшим значением (или с первым найденным нулем) ), считать.

Таким образом, ситуация здесь немного усложняется тем, что потоки, которые вы хотите заполнить, будут теми, с наименьшим количеством работы. Это требует, чтобы вы проверили 4 counts и выбрали очередь. Однако, поскольку существует только один производитель, вы, вероятно, можете просто сканировать очередь без блокировки. Логика здесь в том, что потребители не будут затронуты чтением, и выбор потока на самом деле не будет неверным, даже если потребители будут работать во время этого выбора.

Таким образом, у меня был бы массив объектов потока, каждый из которых имел бы счетчик и мьютекс для блокировки.

1.Инициализация счетчика всех закрытых очередей =0

Инициализируйте счетчики в конструкторах — убедитесь, что производитель не работает во время инициализации, и синхронизация не будет проблемой.

2.counter++ при отправке задачи *3.counter-- при извлечении задачи*

Реализуйте 2 метода для объекта потока, чтобы выполнить постановку/удаление из очереди, и в каждом из них используйте lock_guard для блокировки мьютекса (техника RAII). Затем нажмите/извлеките элемент в/из очереди и увеличьте/уменьшите при необходимости.

C++11: lock_guard http://en.cppreference.com/w/cpp/thread/lock_guard

4.Диспетчер задач видит количество частных целых чисел каждого потока. *5.Отправляет задачи в очередь с минимальным количеством*

Как я сказал выше, если есть только один, вы можете просто просмотреть массив объектов и выбрать (сохранить индекс) объект потока, где счетчик (добавить метод getCount()) является самым низким. Скорее всего, она будет самой низкой, даже если потребители продолжат свою работу.

Если есть несколько потоков, производящих работу, вам, возможно, придется подумать о том, как вы хотите обрабатывать 2 потока, связанных с одним и тем же потоком (это может не иметь значения).

person Caribou    schedule 09.01.2013
comment
@CaribouСпасибо, общая идея будет заключаться в том, чтобы создать массив объектов потоков с конструктором, имеющим счетчик и мьютекс для блокировки. правильный? - person aram; 10.01.2013
comment
да - просто помните, что мое решение выше основано на одном производителе, и если вы увеличите это число, вам нужно будет подумать о том, как они взаимодействуют - например, если оба выбирают одну и ту же очередь. - person Caribou; 10.01.2013
comment
@Caribou Новые задания не создаются программным потоком (извините, я упомянул неправильно) каждый раз, когда я использую парадигму многоскоростного синхронного потока данных, задания создаются графами и узлами. Все задания, созданные из графов и узлов, должны искать минимальные локальные очереди и ставиться в них. поэтому будут ли изменения в шагах реализации, которые вы объяснили выше, когда я использую задания из графов и узлов вместо программных потоков. - person aram; 10.01.2013
comment
ieeexplore.ieee.org/xpl/ что вы делаете? (на том же стадионе?) - person Caribou; 10.01.2013
comment
да, это то, что я делаю. Парадигма многоскоростного синхронного потока данных - person aram; 10.01.2013
comment
Основная идея останется той же, конечно, в C++11 вы будете использовать те же классы и вызовы. Потоки обработки по-прежнему могут храниться в массиве, но при наличии нескольких модулей записи вы можете столкнуться с конфликтом/блокировкой. Я бы сказал, построить его, а затем улучшить его. НО это очень сложная область, и мне кажется, что было бы неплохо найти старшего программиста / лектора (?), который мог бы помочь вам определить, что вам конкретно нужно делать. Я не смогу дать вам определенное решение, не изучив домен должным образом (извините, я не могу сделать больше, чем у меня есть) - - person Caribou; 10.01.2013
comment
@Caribouplease, не извиняйтесь, теперь у меня есть основная идея, как вы сказали, bulid, а затем улучшайте. Сначала я попытаюсь построить логический поток кода в основном, и я могу подумать и сделать это для конкретной предметной области. Я надеюсь, что смогу задать вам сомнения при построении основного логического потока кода идеи. Спасибо - person aram; 10.01.2013