2012-05-10 13 views
6

Ho appena notato il problema con il processo terminato (dal metodo multiprocessing library) su Linux. Ho un'applicazione che funziona con la libreria multiprocessing ma ... quando chiamo la funzione terminate su Windows tutto funziona alla grande, d'altra parte Linux non riesce con questa soluzione. Come sostituzione del processo di omicidio sono stato costretto a usareIl processo di multiprocesso termina con esito negativo su Linux

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

So che questo non è troppo intelligente, ma funziona. Quindi mi chiedo solo perché questo codice funzioni su Windows, ma su Linux fallisce.

Esempio:

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 

La mia configurazione: python 3.2.0 costruire 88.445; Linux-2.6.32-Debian-6.0.4

Questo è un esempio del mio codice. Spero che sarà sufficiente.

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

Puoi pubblicare altro codice? Sarebbe utile sapere cosa sta facendo foo con la barra, e da ciò probabilmente avremmo un'idea migliore del perché Linux non lo stia uccidendo, ma Windows lo è. – parselmouth

risposta

5

Dal docs:

terminate()

terminare il processo. Su Unix questo viene fatto usando il segnale SIGTERM ; su Windows viene utilizzato TerminateProcess(). Nota che i comandi di uscita e infine le clausole, ecc., Non verranno eseguiti.

Nota che i processi discendenti del processo non verranno terminati - diventeranno semplicemente orfani.

Quindi sembra che devi assicurarti che il tuo processo gestisca correttamente il segnale SIGTERM.

Utilizzare signal.signal per impostare un gestore di segnale.

Per impostare un gestore di segnale SIGTERM che semplicemente esiste il processo, utilizzare:

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

EDIT

Un processo Python termina normalmente su SIGTERM, non so il motivo per cui il processo di multiprocessing doesn terminare su SIGTERM.

0

Non è esattamente una risposta diretta alla tua domanda, ma dal momento che avete a che fare con i fili questo potrebbe essere utile pure per il debug di quei fili: https://stackoverflow.com/a/10165776/1019572 Recentemente ho trovato un bug in cherrypy utilizzando questo codice.

Problemi correlati