2012-05-10 8 views
6

Ich habe gerade das Problem mit Prozess beendet (von multiprocessing Bibliothek) -Methode auf Linux. Ich habe Anwendung mit multiprocessing Bibliothek arbeiten, aber ... wenn ich terminate Funktion unter Windows aufrufen funktioniert alles super, auf der anderen Seite scheitert Linux mit dieser Lösung. Als Ersatz für Prozess Tötung wurde ich gezwungen,Multiprocessing Prozess beendet unter Linux

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

Ich weiß, das ist nicht zu schlau, aber es funktioniert. Ich frage mich also, warum dieser Code unter Windows funktioniert, aber unter Linux schlägt fehl.

Beispiel:

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 

Meine Konfiguration: Python 3.2.0 88445 bauen; Linux-2.6.32-Debian-6.0.4

Dies ist ein Beispiel aus meinem Code. Ich hoffe es wird ausreichen.

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

Können Sie mehr von Ihrem Code posten? Es wäre hilfreich zu wissen, was foo mit bar macht, und davon würden wir wahrscheinlich eine bessere Vorstellung davon bekommen, warum Linux es nicht umbringt, aber Windows ist es. – parselmouth

Antwort

5

Vom docs:

beenden()

den Prozess beenden. Unter Unix geschieht dies mit dem Signal SIGTERM; Unter Windows wird TerminateProcess() verwendet. Beachten Sie, dass exit Handler und schließlich Klauseln usw. nicht ausgeführt werden.

Beachten Sie, dass abgeleitete Prozesse des Prozesses nicht beendet werden - werden sie einfach verwaist.

Es sieht also so aus, als müssten Sie sicherstellen, dass Ihr Prozess das SIGTERM-Signal korrekt verarbeitet.

Verwenden Sie signal.signal, um einen Signal-Handler zu setzen.

Um ein SIGTERM Signal-Handler gesetzt, die einfach den Prozess vorhanden ist, verwenden:

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

EDIT

Ein Python-Prozess normalerweise auf SIGTERM beendet, ich weiß nicht, warum Ihr Multiprozessing Prozess doesn Beenden Sie nicht auf SIGTERM.

0

Nicht gerade eine direkte Antwort auf Ihre Frage, aber da man mit den Themen beschäftigen dies für das Debuggen, diese Themen auch hilfreich sein könnten: https://stackoverflow.com/a/10165776/1019572 Vor kurzem fand ich einen Fehler in cherrypy diesen Code verwenden.

Verwandte Themen