2012-05-10 31 views
6

Tôi vừa nhận thấy vấn đề với phương pháp chấm dứt quá trình (từ multiprocessing thư viện) trên Linux. Tôi có ứng dụng làm việc với thư viện multiprocessing nhưng ... khi tôi gọi chức năng terminate trên Windows hoạt động tốt, mặt khác Linux không thành công với giải pháp này. Khi thay thế quy trình giết người, tôi buộc phải sử dụngQuá trình đa xử lý chấm dứt không thành công trên Linux

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

Tôi biết điều này không quá thông minh, nhưng nó hoạt động. Vì vậy, tôi chỉ tự hỏi tại sao mã này hoạt động trên Windows, nhưng trên Linux không thành công.

Ví dụ:

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 

cấu hình của tôi: python 3.2.0 xây dựng 88.445; Linux-2.6.32-Debian-6.0.4

Đây là mẫu từ mã của tôi. Tôi hy vọng nó sẽ là đủ.

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

Bạn có thể đăng thêm mã của mình không? Sẽ rất hữu ích nếu biết foo đang làm gì với thanh, và từ đó chúng ta có thể hiểu rõ hơn lý do tại sao Linux không giết nó, nhưng Windows là. – parselmouth

Trả lời

5

Từ docs:

chấm dứt()

Chấm dứt quá trình này. Trên Unix, điều này được thực hiện bằng cách sử dụng tín hiệu SIGTERM; trên Windows TerminateProcess() được sử dụng. Lưu ý rằng các lệnh xử lý và các mệnh đề cuối cùng, v.v., sẽ không được thực thi.

Lưu ý rằng quá trình con cháu của quá trình sẽ không bị chấm dứt - chúng sẽ đơn giản trở thành mồ côi.

Vì vậy, có vẻ như bạn phải đảm bảo rằng quy trình xử lý tín hiệu SIGTERM chính xác.

Sử dụng signal.signal để đặt trình xử lý tín hiệu.

Để thiết lập một handler tín hiệu SIGTERM mà chỉ đơn giản tồn tại quá trình này, sử dụng:

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

EDIT

Một quá trình Python thường chấm dứt vào SIGTERM, tôi không biết tại sao quá trình đa của bạn doesn không chấm dứt trên SIGTERM.

0

Không chính xác một câu trả lời trực tiếp câu hỏi của bạn, nhưng kể từ khi bạn đang đối phó với các chủ đề này có thể là hữu ích cũng để gỡ lỗi những đề: https://stackoverflow.com/a/10165776/1019572 Gần đây tôi đã tìm thấy một lỗi trong CherryPy sử dụng mã này.

Các vấn đề liên quan