Мультипроцессинг - передать общую очередь и уникальный номер для каждого работника - PullRequest
0 голосов
/ 27 января 2019

Я не могу найти решение для кода, где я передаю каждому работнику Shared Queue, но также номер для каждого работника.

Мой код:

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

from multiprocessing import Pool,Queue
from functools import partial
import pygame
queue = Queue()


def play_song(shared_queue, chnl):

    channel = pygame.mixer.Channel(chnl)
    while True:
        sound_name = shared_queue.get()
        channel.play(pygame.mixer.Sound(sound_name))



if __name__ == "__main__":
    channels= [0,1, 2, 3, 4]

    func = partial(play_song,queue)
    p = Pool(5,func, (channels,))

Этот код конечно не возвращает никакой ошибки, потому что она мультипроцессорная, но проблема в том, что каналов передается в play_songкак весь список вместо того, чтобы быть сопоставленным со всеми работниками.

Таким образом, в основном вместо каждого работника инициализируйте канал следующим образом:

channel = pygame.mixer.Channel(0) # each worker would have number from list so 1,2,3,4

Я получаю это

channel = pygame.mixer.Channel([0,1,2,3,4]) # for each worker

Я пытался играть с частичной функцией, но безуспешно.

Я успешно справился с функцией pool.map, но, хотя я мог передавать отдельные номера из списка каналов, я не мог разделить Очередь среди рабочих

1 Ответ

0 голосов
/ 28 января 2019

В конце концов я нашел решение моей проблемы Pygame, которое не требует потоков или многопроцессорной обработки.


Предпосылки проблемы:

Я работал с Pyaudio, и, поскольку он довольно низкоуровневый API для аудио, у меня были проблемы со смешиванием нескольких звуков одновременно и в целом.Причины:

1) Нелегко (возможно, невозможно) запустить несколько потоков одновременно или подавать эти потоки одновременно (похоже на аппаратную проблему)

2) На основе 1) Я попробовал другое отношение - есть один поток, в котором звуковые волны из разных звуков суммируются перед входом в поток - чтоработает, но ненадежно, так как добавление аудиоволн не совсем совместимо - добавление большого количества волн приводит к «растрескиванию звука», так как амплитуды слишком велики.

На основе 1) и 2) Я хотел попробовать запустить потоки в разных процессах, поэтому этот вопрос.


Решение Pygame (одиночная обработка):

for sound_file in sound_files:
    availible_channel = pygame.mixer.find_channel() #if there are 8 channels, it can play 8 sounds at the same time
    availible_channel.play(sound_file )

, если звуковые_файлы уже загружены, это дает почти одновременные результаты.

Многопроцессорное решение

Спасибо Darkonaut, который указалмногопроцессорный метод, мне удается ответить на мои вопросыl вопрос о многопроцессорности, на который, я думаю, уже дан ответ на stackoverflow, но я его включу.

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

import multiprocessing as mp

shared_queue = mp.Queue()


def channel(que,channel_num):
    que.put(channel_num)

if __name__ == '__main__':
    processes = [mp.Process(target=channel, args=(shared_queue, channel_num)) for channel_num in range(8)]

    for p in processes:
        p.start()

    for i in range(8):
        print(shared_queue.get())
    for p in processes:
        p.join()
...