2012-05-09 45 views
33

Tôi đang cố gắng hiểu các khái niệm cơ bản về luồng và đồng thời. Tôi muốn một trường hợp đơn giản, nơi hai chủ đề liên tục cố gắng truy cập vào một tài nguyên được chia sẻ.Threading Python. Làm thế nào để khóa một sợi?

Mã:

import threading 

class Thread(threading.Thread): 
    def __init__(self, t, *args): 
     threading.Thread.__init__(self, target=t, args=args) 
     self.start() 
count = 0 
lock = threading.Lock() 

def incre(): 
    global count 
    lock.acquire() 
    try: 
     count += 1  
    finally: 
     lock.release() 

def bye(): 
    while True: 
     incre() 

def hello_there(): 
    while True: 
     incre() 

def main():  
    hello = Thread(hello_there) 
    goodbye = Thread(bye) 

    while True: 
     print count 

if __name__ == '__main__': 
    main() 

Vì vậy, tôi có hai đề, cả hai cố gắng để tăng bộ đếm. Tôi nghĩ rằng nếu chuỗi 'A' được gọi là incre(), thì lock sẽ được thiết lập, ngăn không cho 'B' truy cập cho đến khi 'A' được phát hành.

Chạy để làm rõ rằng đây không phải là trường hợp. Bạn nhận được tất cả các số liệu ngẫu nhiên của cuộc đua.

Đối tượng khóa được sử dụng chính xác như thế nào?

Chỉnh sửa, Ngoài ra, tôi đã thử đặt các khóa bên trong các chức năng của chuỗi, nhưng vẫn không có may mắn.

+0

Mã của bạn không chạy. –

+0

@Ignacio Vazquez-Abrams - Hiện tại. Tôi đã bỏ qua bit 'if __name__'. Đó là những gì bạn đang đề cập đến? – Zack

+1

Nó cũng không chạy cho tôi. Tôi sẽ mong đợi tạo thread của bạn trông giống như: 'hello = threading.Thread (target = hello_there)' và sau đó cho thread được bắt đầu 'hello.start()'. –

Trả lời

40

Bạn có thể thấy rằng các khóa của mình hoạt động khá nhiều khi bạn đang sử dụng chúng, nếu bạn làm chậm quá trình và làm cho chúng bị chặn nhiều hơn một chút. Bạn đã có ý tưởng đúng, nơi bạn bao quanh các đoạn mã quan trọng bằng khóa. Dưới đây là một điều chỉnh nhỏ cho ví dụ của bạn để cho bạn thấy cách mỗi người chờ đợi nhau để giải phóng khóa.

import threading 
import time 
import inspect 

class Thread(threading.Thread): 
    def __init__(self, t, *args): 
     threading.Thread.__init__(self, target=t, args=args) 
     self.start() 

count = 0 
lock = threading.Lock() 

def incre(): 
    global count 
    caller = inspect.getouterframes(inspect.currentframe())[1][3] 
    print "Inside %s()" % caller 
    print "Acquiring lock" 
    with lock: 
     print "Lock Acquired" 
     count += 1 
     time.sleep(2) 

def bye(): 
    while count < 5: 
     incre() 

def hello_there(): 
    while count < 5: 
     incre() 

def main():  
    hello = Thread(hello_there) 
    goodbye = Thread(bye) 


if __name__ == '__main__': 
    main() 

Mẫu đầu ra:

... 
Inside hello_there() 
Acquiring lock 
Lock Acquired 
Inside bye() 
Acquiring lock 
Lock Acquired 
... 
+0

Ồ, gọn gàng! Tôi đoán tôi đã bị nhầm lẫn bởi 'in đếm' trong' main() 'hiển thị lặp đi lặp lại thất thường. Nhưng tôi đoán nó là loại làm cho rằng tôi đã có ba vòng chạy đồng thời. Cảm ơn! Ngoài ra TIL về mô-đun kiểm tra. Rất tuyệt. – Zack

+0

@Zack: Ya tôi cho rằng đó là bản in chính gây nhầm lẫn cho bạn. Nó không có giới hạn về nó vì vậy nó đã được in nhanh hơn so với các chủ đề thậm chí đã thay đổi nó. – jdi

+0

@jdi Tôi đang cố gắng hiểu khóa, vì vậy tôi đã thêm một bản in (đếm) vào hàm gia tăng của bạn ngay sau khi đếm + = 1, nhưng khi tôi chạy mã nó được 6? – ErinGoBragh

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