2010-07-22 32 views
41

Tôi bắt đầu với nhiều luồng trong python (hoặc ít nhất có thể là tập lệnh của tôi tạo nhiều chuỗi). thuật toán này sẽ được sử dụng đúng đắn của một Mutex? Tôi chưa thử nghiệm mã này và có thể thậm chí sẽ không hoạt động. Tôi chỉ muốn processData chạy trong một thread (một lúc) và vòng lặp chính trong khi tiếp tục chạy, ngay cả khi có một luồng trong hàng đợi.Sử dụng đúng các mutex trong Python

from threading import Thread 
from win32event import CreateMutex 
mutex = CreateMutex(None, False, "My Crazy Mutex") 
while(1) 
    t = Thread(target=self.processData, args=(some_data,)) 
    t.start() 
    mutex.lock() 

def processData(self, data) 
    while(1) 
     if mutex.test() == False: 
      do some stuff 
      break 

Chỉnh sửa: đọc lại mã của tôi Tôi có thể thấy rằng điều đó là sai. nhưng hey, đó là lý do tại sao tôi ở đây yêu cầu giúp đỡ.

+0

nó là rất khó khăn để tìm ra những gì bạn đang cố gắng làm. Bạn sẽ cần giải thích ý định của mình chi tiết hơn. –

+0

@Marcelo Cantos, xin lỗi bạn có lẽ đúng. Tôi muốn mã của tôi trong processData để bắt đầu trong một bước đi mới. Tôi chỉ muốn một luồng để có thể xử lý dữ liệu tại một thời điểm và theo thứ tự dữ liệu nào được gửi để xử lý dữ liệu. Tôi cũng muốn vòng lặp chính trong khi giữ vòng lặp trong khi các luồng khác nằm trong hàng đợi. – Richard

+0

@Richard: Tại sao bạn muốn sử dụng các chủ đề nếu bạn có kế hoạch serialise tất cả các xử lý nào? Có gì sai với một vòng lặp đơn giản? Ngoài ra, tại sao bạn muốn các chủ đề chính để giữ looping? Nó sẽ chỉ đốt cháy CPU, có thể làm đói các luồng khác. –

Trả lời

96

Tôi không biết tại sao bạn sử dụng Mutex của cửa sổ thay vì Python. Sử dụng phương pháp Python, điều này là khá đơn giản:

from threading import Thread, Lock 

mutex = Lock() 

def processData(data): 
    mutex.acquire() 
    try: 
     print('Do some stuff') 
    finally: 
     mutex.release() 

while True: 
    t = Thread(target = processData, args = (some_data,)) 
    t.start() 

Nhưng lưu ý, vì kiến ​​trúc của CPython (cụ thể là Global Interpreter Lock), bạn sẽ có hiệu quả chỉ có một thread chạy tại một thời điểm nào - điều này là tốt nếu một số trong số đó là I/O bị ràng buộc, mặc dù bạn sẽ muốn giải phóng khóa càng nhiều càng tốt để chuỗi I/O bị ràng buộc không chặn các luồng khác chạy.

Cách khác, đối với Python 2.6 trở lên, là sử dụng gói multiprocessing của Python. Nó phản chiếu gói threading, nhưng sẽ tạo ra các quy trình hoàn toàn mới mà có thể chạy đồng thời. Đó là tầm thường để cập nhật ví dụ của bạn:

from multiprocessing import Process, Lock 

mutex = Lock() 

def processData(data): 
    with mutex: 
     print('Do some stuff') 

if __name__ == '__main__': 
    while True: 
     p = Process(target = processData, args = (some_data,)) 
     p.start() 
+0

Tôi đã thử mã của bạn và tôi nhận được lỗi này: với mutex: SyntaxError: cú pháp không hợp lệ. Tôi đoán tôi có thể sử dụng thử: ngoại trừ: trong chức năng của tôi Tôi đang sử dụng python 2.4 – Richard

+4

'with' là Python 2.5 và' multiprocessing' là Python 2.6. Đã chỉnh sửa cho phù hợp. –

+0

Cảm ơn tất cả sự giúp đỡ của bạn, nếu tôi có thể upvote bạn nhiều hơn thì một lần tôi sẽ. Tôi upvoted tất cả các bạn bình luận: D họ đã được hữu ích – Richard

7

Bạn phải mở khóa Mutex của bạn tại một thời điểm nào đó ...

12

Đây là giải pháp tôi đến với:

import time 
from threading import Thread 
from threading import Lock 

def myfunc(i, mutex): 
    mutex.acquire(1) 
    time.sleep(1) 
    print "Thread: %d" %i 
    mutex.release() 


mutex = Lock() 
for i in range(0,10): 
    t = Thread(target=myfunc, args=(i,mutex)) 
    t.start() 
    print "main loop %d" %i 

Output:

main loop 0 
main loop 1 
main loop 2 
main loop 3 
main loop 4 
main loop 5 
main loop 6 
main loop 7 
main loop 8 
main loop 9 
Thread: 0 
Thread: 1 
Thread: 2 
Thread: 3 
Thread: 4 
Thread: 5 
Thread: 6 
Thread: 7 
Thread: 8 
Thread: 9 
+5

Có một bế tắc tiềm ẩn. Nếu lệnh in đưa ra một ngoại lệ, bạn sẽ không bao giờ giải phóng mutex. Bạn cần sử dụng 'try/release' hoặc' with' để đảm bảo khóa được giải phóng. Xem câu trả lời của tôi. –

+2

Ngoài ra, không cần phải vượt qua mutex làm đối số cho hàm. Nó có sẵn trong phạm vi toàn cầu. –

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