2009-03-31 30 views
13

Tôi muốn một bộ quy trình con Python cụ thể có tác động thấp nhất có thể. Tôi đã sử dụng nice để giúp hạn chế mức tiêu thụ CPU. Nhưng lý tưởng I/O cũng sẽ bị hạn chế. (Nếu hoài nghi, hãy làm hài lòng tôi và cho rằng có giá trị trong việc làm này, không quan trọng họ phải mất bao lâu để chạy, có thể có rất nhiều trong số họ, và có những thứ ưu tiên cao hơn (thường là) cùng một máy, v.v.)Làm thế nào để hạn chế tiêu thụ I/O của các quy trình Python (có thể sử dụng ionice)?

Một khả năng có vẻ là ionice. Có bất kỳ gói Python hiện có nào để gọi ionice (Google không bật lên bất kỳ thứ gì) không? Sẽ không khó để viết mã để chỉ cần chạy lệnh ionice; nhưng tôi muốn tránh viết mã mà người khác đã viết/thử nghiệm; đôi khi có trường hợp cạnh tinh tế, vv Và, có cách nào tốt hơn để hạn chế tiêu thụ I/O không?

Các man page for ionice cho thấy rằng giá trị ionice có thể bị ảnh hưởng bởi giá trị nice, nhưng chạy Python 2.6 kịch bản này dường như bác bỏ rằng, ngay cả đối với tiến trình con trong đó giá trị nice được thừa hưởng:

#!/usr/bin/env python 

import os 
import multiprocessing 

def print_ionice(name): 
    print '*** ', name, ' ***' 
    os.system("echo -n 'nice: '; nice") 
    os.system("echo -n 'ionice: '; ionice -p%d" % os.getpid()) 

for niced in (None, 19): 
    if niced: os.nice(niced) 
    print '**** niced to: ', niced, ' ****' 
    print_ionice('parent') 
    subproc = multiprocessing.Process(target=print_ionice, args=['child']) 
    subproc.start() 
    subproc.join() 

Trong đó có đầu ra sau đây:

 
$ uname -as 
Linux x.fake.org 2.6.27-11-server #1 SMP Thu Jan 29 20:13:12 UTC 2009 x86_64 GNU/Linux 
$ ./foo.py 
**** niced to: None **** 
*** parent *** 
nice: 0 
ionice: none: prio 4 
*** child *** 
nice: 0 
ionice: none: prio 4 
**** niced to: 19 **** 
*** parent *** 
nice: 19 
ionice: none: prio 4 
*** child *** 
nice: 19 
ionice: none: prio 4 

Trả lời

14

psutil cho thấy chức năng này (python 2.4 -> 3.2):

import psutil, os 
p = psutil.Process(os.getpid()) 
p.ionice(psutil.IOPRIO_CLASS_IDLE) 

Ngoài ra, bắt đầu từ Python 3.3 này sẽ có sẵn trong python stdlib cũng như: http://bugs.python.org/issue10784

+0

Khắc phục sự cố tuyệt vời, mong muốn nó đã có sẵn cho OSX. –

+0

vâng ... không may OSX chỉ không phơi bày nó một cách tự nhiên. –

+0

Đảm bảo thiết bị chặn của bạn có bộ lập lịch CFQ. Nếu không nó sẽ không hoạt động. – Zorg

3

Tại sao không có bất cứ điều gì ra mắt các quá trình làm ionice trên chúng (ví dụ, r un chúng với ionice) thay vì có chúng ionice mình? Nó có vẻ sạch hơn rất nhiều.

+0

tôi một cách hiệu quả muốn fork và không exec (ví dụ, bằng cách sử dụng mô-đun 'đa xử lý'); không chắc chắn nơi ionice sẽ phù hợp trong đó. Trẻ em * có thể * gọi ionice -p -cblah (trên chính chúng, ví dụ: sử dụng os.system). –

5

Hm.

Là con trỏ bắt đầu, bạn nên tìm số syscall là số gọi ioprio_setioprio_get trong hệ thống hạt nhân của bạn. Tôi khuyên bạn nên đăng ký /usr/include/asm/unistd_32.h hoặc /usr/include/asm/unistd_64.h, tùy thuộc vào cấu trúc hạt nhân của bạn; nếu không có, hãy bắt đầu với đề xuất của trang người đàn ông syscall(2), phải là /usr/include/sys/syscall.h và hoạt động theo cách của bạn bao gồm.

Cho rằng, bạn nên sử dụng ctypes, à la:

def ioprio_set(which, who, ioprio): 
    rc= ctypes.CDLL('libc.so.6').syscall(289, which, who, ioprio) 
    # some error checking goes here, and possibly exception throwing 

Vậy là xong, nhiều hơn hoặc ít hơn. Hãy vui vẻ :)

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