2012-05-10 32 views
6

我剛剛注意到Linux上的進程終止(來自multiprocessing庫)方法的問題。我有應用程序與multiprocessing庫一起工作,但是...當我在Windows上調用terminate函數時,一切都很好,另一方面,Linux使用此解決方案失敗。作爲過程殺手的替代品,我被迫使用多處理進程在Linux上終止失敗

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

我知道這不是太聰明,但它的工作原理。所以我只是想知道爲什麼這個代碼在Windows上工作,但在Linux上失敗。

實施例:

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 

我的配置:3.2.0蟒建立88445; Linux-2.6.32-Debian-6.0.4

這是我的代碼示例。我希望它是足夠的。

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

你能發佈更多的代碼嗎?知道foo在做什麼會有幫助,因此我們可能會更好地瞭解爲什麼Linux不會消除它,但Windows是。 – parselmouth

回答

5

docs

終止()

終止進程。在Unix上,這是通過使用 SIGTERM信號完成的;在Windows上使用TerminateProcess()。請注意,退出 處理程序和finally子句等將不會執行。

請注意,該進程的後代進程將不會終止 - 他們將簡單地成爲孤兒。

所以它看起來像你必須確保你的過程正確處理SIGTERM信號。

使用signal.signal來設置信號處理程序。

要設置簡單的存在過程中的SIGTERM信號處理程序,使用方法:

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

編輯

一個Python程序正常終止對SIGTERM,我不知道爲什麼你的多進程沒有按終止於SIGTERM。