2016-02-06 2 views
0

Краткое описаниеЛегкий способ отличить ОС Python многопроцессорной обработки обрабатывает

Я хотел бы использовать модуль многопроцессорной Python для выполнения нескольких заданий параллельно на сервере Linux. Кроме того, я хотел бы иметь возможность посмотреть запущенные процессы с top или ps и kill один из них, но пусть остальные будут работать.

Однако я вижу, что каждый процесс, запущенный из модуля многопроцессорности Python, похож на команду ps -f.

Все, что я вижу это:

fermion:workspace ross$ ps -f 
    UID PID PPID C STIME TTY   TIME CMD 
    501 32257 32256 0 8:52PM ttys000 0:00.04 -bash 
    501 32333 32257 0 9:05PM ttys000 0:00.04 python ./parallel_jobs.py 
    501 32334 32333 0 9:05PM ttys000 0:00.00 python ./parallel_jobs.py 
    501 32335 32333 0 9:05PM ttys000 0:00.00 python ./parallel_jobs.py 
    501 32336 32333 0 9:05PM ttys000 0:00.00 python ./parallel_jobs.py 
    501 32272 32271 0 8:53PM ttys001 0:00.05 -bash 

Есть ли способ, чтобы получить что-то более описательный в колонке CMD? Нужно ли мне просто отслеживать PID в файлах журналов? Или есть другой вариант?

фон

Я делаю некоторые пакетной обработки, где некоторые рабочие места могут работать в течение нескольких часов. Мне нужно иметь возможность запускать некоторые из этих заданий параллельно, чтобы сэкономить время. И все эти параллельные задания должны быть успешно завершены, прежде чем я смогу запустить другую работу, которая зависит от их всех. Однако, если одно задание неверно, я хочу уметь его убивать, давая возможность другим заполнить ... и это происходит там, где у меня есть одно задание, затем параллельные задания, затем еще несколько заданий, затем несколько параллельных заданий ...

Пример кода

Это некоторый фиктивный код, который описывает концепцию того, что я пытаюсь сделать.

#!/usr/bin/env python 
import time 
import multiprocessing 

def open_zoo_cages(): 
    print('Opening zoo cages...') 

def crossing_road(animal, sleep_time): 
    print('An ' + animal + ' is crossing the road') 
    for i in range(5): 
     print("It's a wide road for " + animal + " to cross...") 
     time.sleep(sleep_time) 

    print('The ' + animal + ' is across.') 

def aardvark(): 
    crossing_road('aardvark', 2) 

def badger(): 
    crossing_road('badger', 4) 

def cougar(): 
    crossing_road('cougar', 3) 

def clean_the_road(): 
    print('Cleaning off the road of animal droppings...') 

def print_exit_code(process): 
    print(process.name + " exit code: " + str(process.exitcode)) 

def main(): 
    # Run a single job that must finish before running some jobs in parallel 
    open_zoo_cages() 

    # Run some jobs in parallel 
    amos = multiprocessing.Process(name='aardvark Amos', target=aardvark) 
    betty = multiprocessing.Process(name='badger Betty', target=badger) 
    carl = multiprocessing.Process(name='cougar Carl', target=cougar) 

    amos.start() 
    betty.start() 
    carl.start() 

    amos.join() 
    betty.join() 
    carl.join() 

    print_exit_code(amos) 
    print_exit_code(betty) 
    print_exit_code(carl) 

    # Run another job (clean_the_road) if all the parallel jobs finished in 
    # success. Otherwise end in error. 
    if amos.exitcode == 0 and betty.exitcode == 0 and carl.exitcode == 0: 
     clean_the_road() 
    else: 
     sys.exit('Not all animals finished crossing') 

if __name__ == '__main__': 
    main() 

Кроме того, я отметил, что ввод одной из функций в другом модуле Python не меняет того, что происходит в столбце ps команды для соответствующего процесса.

Выход

fermion:workspace ross$ ./parallel_jobs.py 
Opening zoo cages... 
An aardvark is crossing the road 
It's a wide road for aardvark to cross... 
An badger is crossing the road 
It's a wide road for badger to cross... 
An cougar is crossing the road 
It's a wide road for cougar to cross... 
It's a wide road for aardvark to cross... 
It's a wide road for cougar to cross... 
It's a wide road for aardvark to cross... 
It's a wide road for badger to cross... 
It's a wide road for cougar to cross... 
It's a wide road for aardvark to cross... 
It's a wide road for badger to cross... 
It's a wide road for aardvark to cross... 
It's a wide road for cougar to cross... 
The aardvark is across. 
It's a wide road for badger to cross... 
It's a wide road for cougar to cross... 
The cougar is across. 
It's a wide road for badger to cross... 
The badger is across. 
aardvark Amos exit code: 0 
badger Betty exit code: 0 
cougar Carl exit code: 0 
Cleaning off the road of animal droppings... 
+0

контроль этот пост: http://stackoverflow.com/questions/564695/is-there-a-way-to-change-effective-process-name-in-python .. один из ответы упоминают https://github.com/dvarrazzo/py-setproctitle, которые могут сработать для вас. Это не похоже, что есть способ сделать это в vanilla python. –

+0

Хм ... это интересно. Я думаю, что мне придется использовать multiprocessing.current_process(). Pid, ​​а затем использовать эту библиотеку python (написанную на C, похоже), чтобы изменить имя процесса. –

ответ

1

Приятный простой ответ, у каждого процесс открытия описательного дескриптора файла, а затем использовать LSOF.

f = open('/tmp/hippo.txt','w') 

это даст вам PID для процесса

lsof | grep "hippo" 

это не самый вещий ответ, но так, что:)

Мой первоначальный ответ был легкий путь, вот неполный крошечный пример более крупной концепции, добавляющий обработчик сигнала к классу, называемому подпроцессом, позволяет вам выпустить что-то вроде kill -6 ... для выгрузки информации ....Вы можете даже использовать его по требованию выливать прогресса, сколько осталось обработать в данном подпроцесса,

import signal 
class Foo(): 
    def __init__(self, name): 
     self.myname = name 
     signal.signal(signal.SIGTERM, self.my_callback) 
     self.myqueue = Queue.Queue() 

    def my_callback(self): 
     logging.error("%s %s %s", self.myname, psutil.blah_getmypid(), len(self.myqueue))   

Или вы можете сделать это, что я думаю, может быть то, что вы действительно хотите:

import multiprocess, time 
def foo(): 
    time.sleep(60) 
if __name__ == "__main__": 
    process = [ 
     multiprocessing.Process(name="a",target=foo), 
     multiprocessing.Process(name="b",target=foo), 
     multiprocessing.Process(name="c",target=foo), 
    ] 
    for p in process: 
     p.start() 
    for p in process: 
     print(p.name, p.pid) 
    for p in process: 
     p.join() 
+0

Это работало очень хорошо на моем ноутбуке Mac. Я также постараюсь использовать Linux. –

1

Библиотека Psutil может делать то, что вы ищете, и широко используется. Вы можете узнать, как это работает программист psutil, или использовать библиотеку самостоятельно в своем проекте.

https://pypi.python.org/pypi/psutil

+0

Эта библиотека выглядит очень аккуратно. Однако я не уверен, что бы отличить процессы. Я посмотрел на методы name(), exe() и cmdline() класса Process, и они дают одно и то же для каждого из моих процессов многопроцессорности. (По крайней мере, на моем ноутбуке Mac ... повторю попытку на Linux.) Есть ли что-то еще, что я должен попробовать? –

+0

Думаю, вам нужно искать children() и parent(). Работы, которые вы запускаете параллельно, должны быть дочерними элементами родительского скрипта, который запускает их. – n3storm

+0

Я хочу, чтобы иметь возможность различать детей родительского процесса. Какой из них? Я могу рассказать отношения parent/child только с помощью 'ps'. –

Смежные вопросы