Có thể chạy chức năng trong một quy trình con mà không cần phân luồng hoặc viết một tệp / tập lệnh riêng biệt.


82
import subprocess

def my_function(x):
    return x + 100

output = subprocess.Popen(my_function, 1) #I would like to pass the function object and its arguments
print output 
#desired output: 101

Tôi chỉ tìm thấy tài liệu về cách mở các quy trình con bằng các tập lệnh riêng biệt. Có ai biết cách vượt qua các đối tượng chức năng hoặc thậm chí một cách dễ dàng để vượt qua mã chức năng không?


1
Tôi tin rằng bạn đang tìm kiếm mô-đun đa xử lý .
Noctis Skytower

Câu trả lời:


111

Tôi nghĩ bạn đang tìm kiếm thứ gì đó giống mô-đun đa xử lý hơn:

http://docs.python.org/library/multiprocessing.html#the-process-class

Mô-đun quy trình con dành cho các quy trình sinh sản và thực hiện mọi việc với đầu vào / đầu ra của chúng - không phải để chạy các chức năng.

Đây là multiprocessingphiên bản mã của bạn:

from multiprocessing import Process, Queue

def my_function(q, x):
    q.put(x + 100)

if __name__ == '__main__':
    queue = Queue()
    p = Process(target=my_function, args=(queue, 1))
    p.start()
    p.join() # this blocks until the process terminates
    result = queue.get()
    print result

20
Bạn có thể sử dụng processifytrang trí như một phím tắt: gist.github.com/2311116
schlamar

3
Tôi giả sử rằng điều này sao chép trình thông dịch Python và tất cả môi trường của nó cho quy trình con?
Jens

1
Đây là một nhánh của processify hoạt động trong python 3 và hỗ trợ các chức năng của trình tạo. gist.github.com/stuaxo/889db016e51264581b50
Stuart Axon

4
Lưu ý rằng mã này chứa một bế tắc trong trường hợp bạn đang chuyển dữ liệu lớn không đáng kể qua hàng đợi - luôn queue.get () trước khi tham gia quy trình, nếu không nó sẽ bị treo khi cố gắng ghi vào hàng đợi trong khi không có gì đang đọc nó.
Petr Baudis

@schlamar Tôi muốn chạy một hàm trong nền nhưng tôi có một số hạn chế về tài nguyên và không thể chạy hàm nhiều lần mà tôi muốn và muốn xếp hàng đợi các lần thực thi bổ sung của hàm. Bạn có bất kỳ ý tưởng nào về cách tôi nên làm điều đó? Tôi có câu hỏi của tôi ở đây . Bạn có thể vui lòng xem qua câu hỏi của tôi? Bất kỳ sự trợ giúp nào đều sẽ là tuyệt vời!
Amir

17

Bạn có thể sử dụng lệnh forkgọi hệ thống Unix tiêu chuẩn , như os.fork(). fork()sẽ tạo một quy trình mới, với cùng một tập lệnh đang chạy. Trong quy trình mới, nó sẽ trả về 0, trong khi trong quy trình cũ, nó sẽ trả về ID quy trình của quy trình mới.

child_pid = os.fork()
if child_pid == 0:
  print "New proc"
else:
  print "Old proc"

Đối với thư viện cấp cao hơn, cung cấp hỗ trợ đa xử lý, cung cấp tính trừu tượng di động để sử dụng nhiều quy trình, có mô-đun đa xử lý . Có một bài báo trên IBM DeveloperWorks, Đa xử lý với Python , với phần giới thiệu ngắn gọn về cả hai kỹ thuật.


Tôi tò mò; tại sao lại ủng hộ? Có gì sai trong câu trả lời của tôi không?
Brian Campbell

Đa xử lý không chỉ là một trình bao bọc cấp cao hơn xung quanh fork (), mà nó là một bộ công cụ đa xử lý đa nền tảng (sử dụng fork trên unix). Điều này rất quan trọng, vì điều này có nghĩa là nó chạy trên Windows, trong khi fork () thì không. Chỉnh sửa: Và đây là lý do cho sự phản đối, mặc dù sau đó tôi quyết định rằng nó có lẽ không đáng. Tuy nhiên, quá muộn để lấy lại nó. Chỉnh sửa2: Hay đúng hơn, lý do là fork () được đề xuất khi nó không đa nền tảng.
Devin Jeanpierre

3
@Devin, bạn luôn có thể rút lại phiếu phản đối mà bạn đã làm, nếu bạn muốn.
Alex Martelli

Đã chỉnh sửa để làm rõ điều đó, sau đó. Tôi đã đề cập rõ ràng rằng forkkhông phải là di động; Nói chung, tôi sẽ đưa ra các câu trả lời không di động cùng với thông tin rằng chúng không di động và để người hỏi quyết định xem điều đó có đủ cho họ hay không. Khi tôi đã chỉnh sửa câu trả lời của mình, bạn sẽ có thể loại bỏ phiếu phản đối nếu bạn cảm thấy rằng tôi đã cải thiện nó đủ; mặc dù không có cảm giác khó khăn nếu bạn không, tôi chỉ muốn kiểm tra xem tôi đã sai gì.
Brian Campbell

@Alex, nope, bạn không thể. Sau một khoảng thời gian nhất định, bạn không thể lấy lại, cho đến khi chỉnh sửa xảy ra. Khoảng thời gian như vậy đã trôi qua trước khi tôi nghĩ lại, do đó, nhận xét "quá muộn". Dù sao, như tôi đã nói, tôi đã quyết định nó không đáng, nên nó đã biến mất. Tôi cũng đánh giá cao và hiểu lý do của bạn, và tôi rất vui vì sẽ không có cảm giác khó khăn nào cả. : p
Devin Jeanpierre

5

Bài đăng trên của Brian McKenna về đa xử lý thực sự hữu ích, nhưng nếu bạn muốn đi theo lộ trình phân luồng (trái ngược với dựa trên quy trình), ví dụ này sẽ giúp bạn bắt đầu:

import threading
import time

def blocker():
    while True:
        print "Oh, sorry, am I in the way?"
        time.sleep(1)

t = threading.Thread(name='child procs', target=blocker)
t.start()

# Prove that we passed through the blocking call
print "No, that's okay" 

Bạn cũng có thể sử dụng setDaemon(True)tính năng này để làm nền cho chuỗi ngay lập tức.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.