Python: многопроцессорная обработка вызова функции внутри цикла for, чтобы каждый вызов выполнялся независимо

У меня есть функция, которая шифрует число и сохраняет его в списке

encrypted = [[0]*10]*1000

def encrypt(i):
        encrypted[i]=bin(i)[2:].zfill(10).decode('hex')

Выражение гораздо сложнее, чем это. Я просто привожу пример.

Теперь я хочу вызвать функцию шифрования внутри цикла for с несколькими вызовами в разных процессах или потоках — однако из-за GIL для процесса, связанного с процессором, потоки не помогут — поправьте меня, если я ошибаюсь.

for i in xrange(1000):
     encrypt(i)

Таким образом, цикл не должен ждать завершения шифрования одного значения, чтобы начать следующее.

Таким образом, когда i=1 и происходит шифрование 1, цикл For должен увеличить и начать шифрование 2, а затем 3 одновременно.

Результаты шифрования должны храниться в зашифрованном списке (порядок результатов не важен).


person Abhinav    schedule 02.08.2015    source источник
comment
stackoverflow.com/questions/15143837/   -  person nitimalh    schedule 02.08.2015
comment
Я думаю, что этот пример должен помочь вам объединить ваши значения и иметь оптимальное количество потоков, работающих параллельно.   -  person nitimalh    schedule 02.08.2015


Ответы (2)


Вы можете использовать multithreading.Pool

from multiprocessing import Pool

def encrypt(i):
    return bin(i)[2:].zfill(10).decode('hex')

if __name__ == '__main__':
    pool = Pool(processes=4)  # adjust to number of cores
    result = pool.map(encrypt, range(1000))
    print result
person Daniel Hepper    schedule 03.08.2015
comment
есть ли какой-либо другой способ вызвать шифрование одновременно без использования карты - поскольку результат шифрования переходит в оператор if .. if (len (encrypt (i))‹16)): завершить все процессы .... просто указав пример; итерация для true или false в массиве результатов привела бы к ненужным накладным расходам. - person Abhinav; 03.08.2015
comment
понял .. я использовал imap_unordered вместо карты Спасибо! - person Abhinav; 03.08.2015

Хорошо, сначала несколько советов. В зависимости от количества потоков, которые вам нужно запустить, вы должны проверить PyPy, это похоже на проект, который может принести большую пользу из особенностей pypy.

Вот отредактированный пример из документов Queue, если я понимаю, что вам нужно, чем это должен указать вам правильное направление.

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

def worker():
    while True:
        number = q.get()
        encrypt(number)
        q.task_done()

q = Queue()
for i in range(num_worker_threads):
    t = Thread(target=worker)
    t.daemon = True
    t.start()

for number in numbers:
    q.put(number)

q.join()       # block until all tasks are done
person Fyrn    schedule 02.08.2015
comment
Спасибо @fern - хотя я где-то читал, что для процессов, связанных с ЦП, из-за блокировки глобального интерпретатора запуск нескольких потоков будет бесполезен. Есть ли другой способ выполнить ту же задачу, используя многопроцессорную обработку? - person Abhinav; 03.08.2015
comment
У меня недостаточно представителей, чтобы прокомментировать выбранный ответ, но если для процессов пула установлено значение None, он будет использовать значение, возвращаемое cpu_count(). - person Fyrn; 05.08.2015