Как передать «блокировку» в моем concurrent.futures.ProcessPoolExecutor в Python? - PullRequest
0 голосов
/ 15 апреля 2020

Я запускаю параллельный тест с Python 3.7 и Appium 1.15.1 на реальных Android смартфонах.

Я использую concurrent.futures.ProcessPoolExecutor для запуска каждого теста на каждый смартфон.

Я передаю список идентификаторов смартфонов функции моей карты. Таким образом, мой метод run_smartphone () (который запускает тест) получает идентификатор смартфона и определяет, на каком смартфоне он должен выполнить тест.

Мой скрипт работает без проблем. Но Я хотел бы добавить «блокировку» , потому что run_smartphone () делает некоторые операции ввода-вывода в базе данных sqlite3. Так что поправьте меня, если я ошибаюсь, но было бы неплохо "заблокировать" операцию ввода-вывода для этой базы данных sqlite3?

Вот мой оригинальный код, который работает:

def run_smartphone(p_udid):
    #do the stuff

list_smartphones_connected = [41492968379078, 53519716736397]
with concurrent.futures.ProcessPoolExecutor() as executor:
    try:
        multiprocesses = executor.map(mymodules.run_smartphone, list_smartphones_connected)

    except ValueError:
        print(("Error multiprocesses"))

Поэтому я попытался добавить пароль «lock» в свой метод run_smartphone (). Вот что я написал:

m = multiprocessing.Manager()
lock = m.Lock()
list_arguments_smartphones = []

list_smartphones_connected = [41492968379078, 53519716736397]
for smartphone_connected in list_smartphones_connected:        
    list_arguments_smartphones.append([smartphone_connected, lock])

with concurrent.futures.ProcessPoolExecutor() as executor:
    try:
        multiprocesses = executor.map(mymodules.run_smartphone, list_arguments_smartphones)

    except ValueError:
        print(("Error multiprocesses"))

Но это не работает, и я не получаю никаких исключений. Pycharm останавливает сценарий:

Process finished with exit code 0

Понятия не имею, что останавливает сценарий.

Поэтому я начал исследовать, выполнив сценарий для 1 смартфона с этой строкой:

 multiprocesses = executor.map(mymodules.run_smartphone, [41492968379078,lock])

это дает тот же результат => Остановка сценария, без запуска автоматизации, и я не вижу никаких исключений (Процесс завершен с кодом завершения 0).

Как я хотел знать, где именно была проблема, я запускаю скрипт с «трассировкой».

py -m trace --trace  myscript.py

Но я ничего не понимаю, не вижу ошибок ... Вы можете увидеть вывод этой команды 'trace' в текстовом файле, который я загрузил на GitHub:

https://github.com/gauthierbuttez/public/blob/master/trace-log.txt

Кто-нибудь знает, как я могу передать «блокировку» моему concurrent.futures.ProcessPoolExecutor ()? И это хорошая идея?

Спасибо.

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Да поможет вам это ...

    m = multiprocessing.Manager()
    lock = m.Lock()

    def run_smartphone(p_udid, lock): 
        # further code

    list_smartphones_connected = [41492968379078, 53519716736397] 
    with concurrent.futures.ProcessPoolExecutor() as executor: 
        try: 
            multiprocesses = executor.map(run_smartphone, list_smartphones_connected, [lock]*len(list_smartphones_connected)) 
            for function_return_value in multiprocesses:
                print(function_return_value)

        except ValueError: 
            print(("Error multiprocesses"))
0 голосов
/ 15 апреля 2020

Из документов для map ():

Если забавный вызов c вызывает исключение, то это исключение будет вызвано, когда его значение будет получено из итератор.

Другими словами, вам, вероятно, придется использовать возвращаемое значение run_smartphone:

m = multiprocessing.Manager()
lock = m.Lock()
list_arguments_smartphones = []

list_smartphones_connected = [41492968379078, 53519716736397]
for smartphone_connected in list_smartphones_connected:        
    list_arguments_smartphones.append([smartphone_connected, lock])

with concurrent.futures.ProcessPoolExecutor() as executor:
    try:
        multiprocesses = executor.map(mymodules.run_smartphone, list_arguments_smartphones)

        for function_return_value in multiprocesses:
            print(function_return_value)
            # or do something with the value, like insert into a db

    except ValueError:
        print(("Error multiprocesses"))

Но если у вас возникают проблемы даже при передаче блокировки вашей функции, и вы не потрудились читать документы, тогда я бы посоветовал вам реструктурировать свой код так, чтобы run_smartphone считывал только из базы данных (не требует блокировки), и вы записывали в базу данных в for для l oop (не требует блокировки). В противном случае вы попадете в тупиковое болото.

...