Đầu tiên, khóa được thiết kế để bảo vệ tài nguyên; chủ đề không được 'khóa' hoặc 'mở khóa' chúng/có được/khóa (trên tài nguyên) và/release/a lock (trên tài nguyên).
Bạn là chính xác mà bạn muốn đề để chạy đồng thời càng nhiều càng tốt, nhưng chúng ta hãy nhìn vào điều này:
y=10
def doStuff(x):
global y
a = 2 * y
b = y/5
y = a + b + x
print y
t1 = threading.Thread(target=doStuff, args=(8,))
t2 = threading.Thread(target=doStuff, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
Bây giờ, bạn có thể biết rằng hoặc là một trong những chủ đề có thể hoàn thành và in đầu tiên . Bạn sẽ thấy cả hai đầu ra 30.
Nhưng chúng có thể không.
y là tài nguyên được chia sẻ và trong trường hợp này, các bit đọc và ghi vào y là một phần của cái được gọi là "phần quan trọng" và phải được bảo vệ bằng khóa. Lý do là bạn không nhận được đơn vị công việc: một trong hai luồng có thể đạt được CPU bất cứ lúc nào.
Hãy suy nghĩ về nó như thế này:
t1 được hạnh phúc thực thi mã và nó chạm
a = 2 * y
Bây giờ t1 có a = 20 và dừng thực hiện trong một thời gian. t2 trở nên hoạt động trong khi t1 chờ thêm thời gian CPU. t2 thực hiện:
a = 2 * y
b = y/5
y = a + b + x
vào thời điểm này các biến toàn cục y = 30
t2 dừng dừng một chút và t1 nhặt lên một lần nữa. nó thực thi:
b = y/5
y = a + b + x
Kể từ khi y là 30 khi b đã được thiết lập, b = 6 và y hiện đang thiết lập để 34.
thứ tự của các bản in là không xác định làm tốt và bạn có thể nhận được các 30 đầu tiên hoặc 34 đầu tiên.
sử dụng một khóa, chúng tôi sẽ có:
global l
l = threading.Lock()
def doStuff(x):
global y
global l
l.acquire()
a = 2 * y
b = y/5
y = a + b + x
print y
l.release()
này nhất thiết phải làm cho phần này của mã tuyến tính - chỉ có một thread tại một thời điểm. Nhưng nếu toàn bộ chương trình của bạn là tuần tự bạn không nên sử dụng chủ đề anyway. Ý tưởng là bạn tăng tốc độ dựa trên tỷ lệ phần trăm mã bạn có thể thực thi các khóa bên ngoài và chạy song song. Đây là (một lý do) tại sao sử dụng các luồng trên hệ thống 2 lõi không tăng gấp đôi hiệu suất cho mọi thứ.
bản thân khóa cũng là tài nguyên được chia sẻ, nhưng nó cần phải là: một khi một chuỗi mua khóa, tất cả các chủ đề khác cố gắng lấy/cùng/khóa sẽ chặn cho đến khi nó được giải phóng. Khi nó được phát hành, luồng đầu tiên để di chuyển về phía trước và lấy khóa sẽ chặn tất cả các luồng chờ khác.
Hy vọng điều đó là đủ để tiếp tục!
Không, tôi không hỏi về GIL, tôi biết những hạn chế của nó trong python và tôi hài lòng với nó, câu hỏi là về khóa luồng với get() và release() không liên quan đến GIL (ngoài nó đã khóa tên) – MistahX
Đã gắn thẻ lại, không độc quyền với 'python'. –
được gắn thẻ lại là python, tôi đang đề cập đến các phương pháp khóa trong mô-đun luồng, quên thêm vào trong – MistahX