2012-12-30 70 views
6

Tôi đã tạo các hoán vị với hàm itertools.permutations trong python. Vấn đề là kết quả là rất lớn và tôi muốn đi qua nó với nhiều chủ đề nhưng thật sự không biết làm thế nào để thực hiện điều đó ở đây là những gì tôi có cho đến nay:Các hoán vị Python chủ đề

perms = itertools.permutations('1234', r=4) 

#I would like to iterate through 'perms' with multiple threads 
for perm in perms: 
    print perm 
+0

làm cách nào bạn muốn chia dữ liệu giữa các chuỗi? tại sao bạn muốn sử dụng nhiều chủ đề? –

+0

Tôi muốn chia nó đồng đều: nếu 'perms' chứa 1'000'000 mục và tôi có 4 chủ đề mỗi thread nên xử lý 250'000 mục; Nếu tôi chỉ sử dụng một thread nó mất khoảng 10 phút để đi qua toàn bộ các mục do đó tôi muốn sử dụng nhiều hơn một sợi – wasp256

+0

chính xác quá trình của bạn, IO ràng buộc hoặc CPU bị ràng buộc là gì? –

Trả lời

4

Nếu công việc bạn muốn thực hiện với các mục từ trình tạo hoán vị là CPU chuyên sâu, bạn có thể muốn sử dụng quy trình thay vì chuỗi. Khóa thông dịch toàn cầu của CPython (GIL) làm cho đa luồng có giá trị giới hạn khi thực hiện công việc liên kết CPU.

Thay vào đó, sử dụng lớp Pool các multiprocessing mô-đun, như vậy:

import multiprocessing 
import itertools 

def do_stuff(perm): 
    # whatever 
    return list(reversed(perm)) 

if __name__ == "__main__": 
    with multiprocessing.Pool() as pool: # default is optimal number of processes 
     results = pool.map(do_stuff, itertools.permutations('1234', r=4)) 

     # do stuff with results 

Lưu ý rằng nếu bạn sẽ được lặp lại trên results (chứ không phải làm một cái gì đó với nó như là một danh sách), bạn có thể sử dụng imap thay vì map để có được một iterator mà bạn có thể sử dụng để làm việc trên các kết quả khi chúng được sản xuất từ ​​các quy trình công nhân. Nếu nó không quan trọng thứ tự các mục được trả lại, bạn có thể sử dụng imap_unordered để (tôi nghĩ) tiết kiệm một chút bộ nhớ.

Yêu cầu bản mẫu if __name__ is "__main__" trên Windows, trong đó mô-đun multiprocessing phải làm việc xung quanh giới hạn của hệ điều hành (không fork).

0

mô-đun futures Python làm cho nó dễ dàng phân chia công việc giữa các luồng. Trong ví dụ này, 4 chủ đề sẽ được sử dụng, nhưng bạn có thể sửa đổi nó cho phù hợp với nhu cầu của bạn.

from concurrent import futures 

def thread_process(perm): 
    #do something 

with futures.ThreadPoolExecutor(max_workers=4) as executor: 
    for perm in perms: 
     executor.submit(thread_process, perm) 
+0

vấn đề với việc sử dụng luồng là nó sẽ không làm những gì OP muốn vì GIL nó không thực hiện song song –

+0

Tôi không thấy ở đâu ông nói những gì ông có nghĩa là "đi qua với nhiều chủ đề" - ông có thể làm bất cứ điều gì từ thực hiện một quá trình khác để thực hiện các cuộc gọi socket/file mà khối đề. Trong những trường hợp này, GIL sẽ không gây ra vấn đề gì. Tôi đồng ý rằng nó chắc chắn phụ thuộc vào những gì anh ta muốn làm. –

1

Giả chức năng xử lý của bạn là f (x), bạn muốn làm

from multiprocessing import Pool 

def f(x): 
    return x*x 

if __name__ == '__main__': 
    pool = Pool(processes=4) # start 4 worker processes 
    perms = itertools.permutations('1234', r=4) 
    for r in pool.map(f, perms): 
     print (r) 

Trong thực tế, việc sử dụng đề sẽ không thực hiện các quá trình song song, trừ khi nó được IO bị ràng buộc. Nếu nó là CPU bị ràng buộc và bạn có một lõi tứ, thì đó là con đường để đi. Nếu bạn không có đa lõi và nó là CPU bị ràng buộc, sau đó tôi sợ rằng làm cho nó song song sẽ không cải thiện tình hình hiện tại của bạn.

1

Tách chỉ số số lượng uốn giữa các chủ đề sau đó sử dụng this function để tạo perm từ chỉ mục của nó trong mỗi chuỗi thay vì tạo tất cả các perm và tách chúng giữa các chuỗi.

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