2012-05-10 16 views
6

Acabo de notar el problema con el método de terminación de proceso (desde la biblioteca multiprocessing) en Linux. Tengo una aplicación que funciona con la biblioteca multiprocessing pero ... cuando llamo a la función terminate en Windows todo funciona bien, por otro lado, Linux falla con esta solución. Como reemplazo de matar proceso me vi obligado a utilizarEl proceso de multiprocesamiento finaliza falla en Linux

os.system('kill -9 {}'.format(pid)) 

Sé que esto no es demasiado inteligente, pero funciona. Así que me pregunto por qué este código funciona en Windows, pero en Linux falla.

Ejemplo:

from multiprocessing import Process 
import os 

process=Process(target=foo,args=('bar',)) 
pid=process.pid 
process.terminate() # works on Windows only 

... 

os.sytem('kill -9 {}'.format(pid)) # my replacements on Linux 

Mi configuración: pitón 3.2.0 Build 88445; Linux-2.6.32-Debian-6.0.4

Este es un ejemplo de mi código. Espero que sea suficiente

def start_test(timestamp,current_test_suite,user_ip): 
    global_test_table[timestamp] = current_test_suite 
    setattr(global_test_table[timestamp], "user_ip", user_ip) 
    test_cases = global_test_table[timestamp].test_cases_table 

    test_cases = test_cases*int(global_test_table[timestamp].count + 1) 
    global_test_table[timestamp].test_cases_table = test_cases 
    print(test_cases) 
    print(global_test_table[timestamp].test_cases_table) 

    case_num = len(test_cases) 
    Report.basecounter = Report.casecounter = case_num 

    setattr(global_test_table[timestamp], "case_num", case_num) 
    setattr(global_test_table[timestamp], "user_current_test", 0) 

    try: 
     dbobj=MySQLdb.connect(*dbconnector) 
     dbcursor=dbobj.cursor() 

     dbcursor.execute(sqlquery_insert_progress.format(progress_timestamp = str(timestamp), user_current_test = global_test_table[timestamp].user_current_tes$ 
    except :... 

    for i in range(case_num): 
     user_row = global_test_table[timestamp] 
     current_test_from_tests_table = user_row.test_cases_table[i] 
     unittest.TextTestRunner(verbosity=2).run(suite(CommonGUI.get_address(CommonGUI,current_test_from_tests_table[1], current_test_from_tests_table[2], user$ 
     global_test_table[timestamp].user_current_test = i + 1 
     try: 
      dbobj=MySQLdb.connect(*dbconnector) 
      dbcursor=dbobj.cursor() 

      dbcursor.execute(sqlquery_update_progress.format(progress_timestamp = str(timestamp), user_current_test = global_test_table[timestamp].user_current$ 
     except :... 

@cherrypy.expose() 
def start_test_page(self, **test_suite): 
    timestamp = str(time.time()) 
    user_ip = cherrypy.request.remote.ip 
    if on_server(): 
     sys.stdout=sys.stderr=open("/var/log/cherrypy/test_gui/{file}.log".format(file=timestamp),"a") 
    current_test_suite = self.parse_result(**test_suite) 
    #global_test_table[timestamp] = current_test_suite 
    #setattr(global_test_table[timestamp], "user_ip", user_ip) 
    user_test_process = Process(target=start_test, args=(timestamp,current_test_suite,user_ip)) 
    users_process_table[timestamp] = user_test_process 
    user_test_process.start() 
    return '''{"testsuite_id" : "''' + str(timestamp) + '''"}''' 

@cherrypy.expose() 
def stop_test(self, timestamp): 
    if timestamp in users_process_table: 
     if on_server(): 
      user_process_pid = users_process_table[timestamp].pid 
      os.system("kill -9 " + str(user_process_pid)) 
     else: 
      users_process_table[timestamp].terminate() 
     del users_process_table[timestamp] 
    else: 
     return "No process exists" 
+0

¿Puedes publicar más de tu código? Sería útil saber qué está haciendo foo con barra, y de ahí probablemente obtendríamos una mejor idea de por qué Linux no lo está matando, pero Windows sí. – parselmouth

Respuesta

5

Desde el docs:

terminar()

terminar el proceso. En Unix esto se hace usando la señal SIGTERM ; en Windows TerminateProcess() se usa. Tenga en cuenta que los manejadores de salida y finalmente las cláusulas, etc., no se ejecutarán.

Tenga en cuenta que los procesos descendientes del proceso no se terminarán - simplemente quedarán huérfanos.

Parece que debe asegurarse de que su proceso maneja correctamente la señal SIGTERM.

Utilice signal.signal para establecer un manejador de señal.

Para configurar un manejador de señales SIGTERM que simplemente existe el proceso, utilice:

import signal 
import sys 
signal.signal(signal.SIGTERM, lambda signum, stack_frame: sys.exit(1)) 

EDITAR

Un proceso de Python normalmente termina en SIGTERM, no sé por qué el proceso de multiprocesamiento doesn No termines en SIGTERM.

0

No es exactamente una respuesta directa a su pregunta, pero ya que se trata de los hilos esto podría ser útil también para la depuración de los hilos: https://stackoverflow.com/a/10165776/1019572 poco encontré un error en cherrypy utilizando este código.

Cuestiones relacionadas