Как проверить, работает ли вообще не один, а какой-либо подпроцесс Popen?

#python #python-3.x #subprocess #popen #sys

Вопрос:

Я знаю, что есть возможность проверить, все еще ли выполняется подпроцесс с помощью .poll(). Так, например:

 p = subprocess.Popen(...
"""
A None value indicates that the process hasn't terminated yet.
"""
poll = p.poll()
if poll is None:
  # p.subprocess is alive
 

В моем случае я выполняю несколько одних и тех же подпроцессов одновременно и сохраняю их в списке под названием proc. Каждый раз, когда мне нужен новый подпроцесс, я просто звоню:

 proc.append(subprocess.Popen([sys.executable,...
 

.poll() не будет принимать значения списка, поэтому у кого-нибудь есть для меня рабочий пример того, как я могу проверить, выполняется ли вообще какой-либо подпроцесс с подпроцессами, хранящимися внутри списка?

Это мое обновление до сих пор:

 proc.append(subprocess.Popen([sys.executable,....


def evaluate():
    global proc
    global p
    p = []
    for t in proc:
        print(t.poll())
        if t.poll() is None:
            p.append(0)
        else:
            p.append(1)


evaluate()
if 1 in p:
    #some tasks running
else:
    #no task running
 

Комментарии:

1. почему вы не можете просмотреть список? for process in proc: print(process.poll())

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

3. вы сохраняете их в список, чтобы ссылка сохранялась там, вы даже не пытались это сделать?

4. Да, последние два часа я пытался разобраться в этом сам. Однако мне это пока не удалось. Где я могу опубликовать больше кода, потому что он, похоже, не работает внутри этого комментария?

5. Почему бы не использовать встроенный any , например, с генераторным выражением if any(t.poll() is None for t in proc): print('something is running') ?

Ответ №1:

Как предлагает Matiiss, вы можете перебирать список или получать доступ к элементам в списке по индексу, например.

 >>> slp = []
>>> slp.append(subprocess.Popen(['sleep', '40']))
>>> slp.append(subprocess.Popen(['sleep', '40']))
>>> slp[1].poll()
>>> slp[1].poll()
>>> slp[1].poll()
>>> slp[1].poll()
>>> slp[1].poll()
>>> slp[1].poll()
0
 

или:

 >>> for i in slp:
...  i.poll()
 

Со ссылкой на ваш комментарий:

 >>> slp = []
>>> slp.append([subprocess.Popen(['sleep', '40']), None])
>>> slp.append([subprocess.Popen(['sleep', '40']), None])
>>> if slp[1][0].poll() == 0:
...    slp[1][1] = "Finished"
... 
>>> slp
[[<subprocess.Popen object at 0x7f17b1280a90>, None], [<subprocess.Popen object at 0x7f17b0bb0550>, None]]
>>> if slp[1][0].poll() == 0:
...    slp[1][1] = "Finished"
... 
>>> slp
[[<subprocess.Popen object at 0x7f17b1280a90>, None], [<subprocess.Popen object at 0x7f17b0bb0550>, 'Finished']]
 

Цикл отличается тем, что цикл извлекает элемент списка, который сам по себе является списком [подпроцесс, переменная]:

 >>> slp = []
>>> slp.append([subprocess.Popen(['sleep', '40']), None])
>>> slp.append([subprocess.Popen(['sleep', '40']), None])
>>> for i in slp:
...     if i[0].poll() == 0:
...         i[1] = "finished"
... 
>>> slp
[[<subprocess.Popen object at 0x7f17b0ba7ef0>, None], [<subprocess.Popen object at 0x7f17b0b64cf8>, None]]

>>> for i in slp:
...     if i[0].poll() == 0:
...         i[1] = "finished"
... 
>>> slp
[[<subprocess.Popen object at 0x7f17b1280a90>, 'finished'], [<subprocess.Popen object at 0x7f17b0bb0550>, 'finished']]
 

Комментарии:

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

2. Это другой вопрос, но упрощенно вы бы проверили в цикле и присвоили его другой переменной. Ваш список proc может быть списком списков, где, например, второй элемент является still running переменной. Или вы можете определить вторичный список результатов, соответствующий этому proc списку. Смотрите мою правку.