2010-05-21 38 views
7

Tôi đang làm việc với một hệ thống cụm trên Linux (www.mosix.org) cho phép tôi chạy các công việc và có hệ thống chạy chúng trên các máy tính khác nhau. Jobs đang chạy như vậy:Làm thế nào để nói id quá trình trong Python

mosrun ls & 

này tự nhiên sẽ tạo ra quá trình này và chạy nó trên nền, trở về quá trình id, như vậy:

[1] 29199 

Sau đó nó sẽ trở lại. Tôi đang viết một cơ sở hạ tầng Python sẽ chạy các công việc và kiểm soát chúng. Cho rằng tôi muốn chạy công việc bằng cách sử dụng chương trình mosrun như trên, và lưu ID quá trình của quá trình sinh sản (29199 trong trường hợp này). Điều này tự nhiên không thể được thực hiện bằng cách sử dụng os.system hoặc commands.getoutput, như là ID in không phải là những gì quá trình in để đầu ra ... Bất kỳ manh mối?

Sửa:

Kể từ khi kịch bản python chỉ có nghĩa là để bước đầu chạy kịch bản, kịch bản cần phải chạy dài hơn vỏ python. Tôi đoán nó có nghĩa là quá trình mosrun không thể là quá trình con của kịch bản. Bất kỳ đề xuất?

Cảm ơn

+0

Quy trình con thông thường tiếp tục chạy khi quá trình cha mẹ chết. –

Trả lời

2

Có vẻ như bạn muốn đảm bảo quá trình con là daemonized - PEP 3143, mà tôi đang trỏ đến, tài liệu và điểm đến triển khai tham chiếu cho điều đó và chỉ cho người khác.

Khi quá trình của bạn (vẫn chạy mã Python) được daemonized, có thể là do các phương tiện hiện đã có bằng PEP 3143 hoặc những người khác, bạn có thể os.execl (hoặc khác os.exec... chức năng) Mã mục tiêu của bạn - điều này cho biết mã chạy mục tiêu trong chính xác cùng một quá trình mà chúng ta vừa nói là được thực hiện, và vì vậy nó tiếp tục được làm daemon, như mong muốn.

Bước cuối cùng không thể sử dụng subprocess vì nó cần phải chạy trong cùng quá trình (daemonized), đè mã thực thi của nó - chính xác những gì os.execl và bạn bè dành cho. Bước đầu tiên, trước khi daemon hóa, có thể được thực hiện thông qua subprocess, nhưng đó là một chút bất tiện (bạn cần phải đặt mã daemonize-then-os.exec trong một riêng biệt .py): phổ biến nhất bạn chỉ muốn os.fork và ngay lập tức daemonize quá trình con.

subprocess khá thuận tiện như một cách đa nền tảng để chạy các quy trình khác, nhưng thực sự không thể thay thế phương pháp "ngã ba và thực thi" cũ của Unix cho các ứng dụng nâng cao (chẳng hạn như daemonization, trong trường hợp này) - - đó là lý do tại sao nó là một điều tốt mà thư viện chuẩn Python cũng cho phép bạn làm việc sau thông qua các chức năng trong mô-đun os! -)

+0

Cảm ơn bạn. Và tôi sẽ có thể biết được quá trình id của quá trình daemonized từ quá trình cũ? –

+0

Dĩa kép đứng một chút, vì vậy bạn cần truyền đạt nó - ví dụ, quá trình con có thể ghi id tiến trình của cháu vào 'stdout' (nơi mà tiến trình cha có thể lấy nó từ ngay) phân chia và trước khi nó chấm dứt. Bạn cần phải đưa ra giao thức riêng của bạn cho rằng, mặc dù, như không có một trong những thành lập trong thư viện Python tiêu chuẩn. –

3

Sử dụng mô-đun subprocess. Popen trường hợp có thuộc tính pid.

+0

Tuyệt vời - cũng đang tìm kiếm – wvd

+0

Điều này không có nghĩa là quy trình mới của tôi sẽ là con trai của quá trình python? điều gì sẽ xảy ra khi tôi chấm dứt quá trình python? (xem chỉnh sửa). Cảm ơn –

0

Cảm ơn tất cả vì sự giúp đỡ. Đây là những gì tôi đã làm cuối cùng, và dường như làm việc ok. Mã sử ​​dụng python-daemon. Có lẽ một cái gì đó thông minh hơn nên được thực hiện về chuyển id quá trình từ đứa trẻ cho người cha, nhưng đó là phần dễ dàng hơn.

import daemon 
def run_in_background(command, tmp_dir="/tmp"): 

    # Decide on a temp file beforehand 
    warnings.filterwarnings("ignore", "tempnam is a potential security") 
    tmp_filename = os.tempnam(tmp_dir) 

    # Duplicate the process 
    pid = os.fork() 


    # If we're child, daemonize and run 
    if pid == 0: 
     with daemon.DaemonContext(): 
      child_id = os.getpid() 
      file(tmp_filename,'w').write(str(child_id)) 
      sp = command.split(' ') 
      os.execl(*([sp[0]]+sp)) 
    else: 
     # If we're a parent, poll for the new file 
     n_iter = 0 
     while True: 
      if os.path.exists(tmp_filename): 
       child_id = int(file(tmp_filename, 'r').read().strip()) 
       break 

      if n_iter == 100: 
       raise Exception("Cannot read process id from temp file %s" % tmp_filename) 
      n_iter += 1 

      time.sleep(0.1) 

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