У меня есть четыре потока, которые имеют свою собственную частную очередь и член 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