Каждый рабочий процесс работает циклично: обрабатывает пакет элементов, добавляя его в свою суперпакет, проверяет, может ли общий процессор принять свою суперпакет сейчас, и, если он не может, переходит к обработке другого пакета элементов, добавляя его в свой суперпакет.
Это продолжается до тех пор, пока суперпакет рабочего процесса не достигнет максимальной мощности общего процессора. (Н). Когда размер суперпакета работника достигает N, он блокируется, ожидая освобождения ресурса.
Мы хотим, чтобы работники с меньшими суперпакетами (от 1 до N) могли проверять — без блокировки — может ли общий процессор принять их, и сразу использовать, если это возможно.
Я подумал, что мы сможем используйте для этого multiprocessing.Semaphore, но семафоры имеют логический тип: да или нет. Вы можете создать N семафоров, чтобы рабочие могли принимать один или несколько семафоров, но невозможно взять более одного атомарно, и в результате вы попадаете в тупик, когда каждый из двух тяжелых рабочих хватает пару, не позволяя друг другу работать.
- Нам не нужно, чтобы это было справедливо — нет необходимости обеспечивать FIFO.
- Мы предпочитаем, чтобы самые большие рабочие процессы (те, чьи суперпакеты уже достигли полного N) имели приоритет над легковесными, которые все еще наращивают свои.
- Тем не менее, если легковесный процесс проверяет и общий процессор может его разместить, поскольку он только обрабатывает другой легковесный процесс, новый облегченный метод - самый большой среди них, который подходит - должен быть разрешен.
Мобильная версия