2010-02-06 3 views
11

Điều này nghe có vẻ giống như một câu hỏi ngu ngốc, nhưng nếu một trong những khóa tài nguyên trong một ứng dụng đa luồng, sau đó hoạt động xảy ra trên tài nguyên, được thực hiện nguyên tử?Là một khóa (luồng) nguyên tử?

I.E .: Bộ vi xử lý có thể bị gián đoạn hoặc có thể chuyển đổi ngữ cảnh xảy ra trong khi tài nguyên đó có khóa không? Nếu có, thì không có gì khác có thể truy cập tài nguyên này cho đến khi nó được lập lịch trở lại để kết thúc quá trình của nó. Âm thanh như một hoạt động đắt tiền.

Trả lời

16

Bộ vi xử lý rất chắc chắn vẫn chuyển sang chủ đề khác, có. Thật vậy, trong hầu hết các máy tính hiện đại có thể có nhiều chủ đề chạy đồng thời anyway. Việc khóa chỉ đảm bảo rằng không có chuỗi nào khác có thể có được cùng một khóa, vì vậy bạn có thể đảm bảo rằng hoạt động trên tài nguyên đó là nguyên tử về tài nguyên đó. Mã sử ​​dụng các tài nguyên khác có thể hoạt động hoàn toàn độc lập.

Bạn thường nên khóa cho các hoạt động ngắn bất cứ khi nào có thể. Bạn cũng có thể chọn độ chi tiết của khóa ... ví dụ: nếu bạn có hai biến độc lập trong đối tượng được chia sẻ, bạn có thể sử dụng hai khóa riêng biệt để bảo vệ quyền truy cập vào các biến đó. Điều đó sẽ có khả năng cung cấp đồng thời tốt hơn - nhưng đồng thời, nhiều khóa hơn có nghĩa là phức tạp hơn và tiềm năng hơn cho bế tắc. Luôn luôn có một hành động cân bằng khi nói đến đồng thời.

+0

vì vậy sau đó nếu một chuỗi khác đang chờ tài nguyên đó, nó chỉ phải chờ đợi? –

+1

@ Tony - yep, nó sẽ chặn chờ đợi để có được khóa cho đến khi nó được phát hành bởi các chủ đề đầu tiên – Paolo

+4

Vâng, tất nhiên. Đó là điều người ta muốn từ một cái khóa. – botismarius

7

Bạn hoàn toàn đúng. Đó là một lý do tại sao nó rất quan trọng để khóa trong thời gian ngắn. Tuy nhiên, điều này không phải là xấu như nó âm thanh vì không có chủ đề khác đang chờ đợi trên khóa sẽ được lên kế hoạch cho đến khi chủ đề giữ khóa phát hành nó.

+1

"Đó là một lý do tại sao nó rất quan trọng để khóa trong thời gian ngắn" ?????? NHƯNG một phần bị khóa của một chủ đề CÓ THỂ ĐƯỢC CHỨNG NHẬN bị gián đoạn bởi một luồng khác. Để được chính xác, bởi bất kỳ chủ đề mà không sử dụng cùng một khóa. – ulrichb

2

Có, một công tắc ngữ cảnh chắc chắn có thể xảy ra. Đây chính là lý do tại sao khi truy cập vào một tài nguyên được chia sẻ, điều quan trọng là phải khóa nó từ một luồng khác. Khi luồng A có khóa, luồng B không thể truy cập mã bị khóa.

Ví dụ, nếu hai luồng chạy đoạn mã sau:

1. lock(l); 
2. -- change shared resource S here -- 
3. unlock(l); 

Một chuyển đổi bối cảnh có thể xảy ra sau khi bước 1, nhưng các chủ đề khác không thể giữ khóa ở thời điểm đó, và do đó, không thể thay đổi tài nguyên chia sẻ . Nếu truy cập vào tài nguyên được chia sẻ trên một trong các chủ đề được thực hiện mà không cần khóa - những điều xấu có thể xảy ra!

Về sự lãng phí, có, đó là một phương pháp lãng phí. Đây là lý do tại sao có những phương pháp cố gắng tránh khóa hoàn toàn. Những phương pháp này được gọi là lock-free và một số phương pháp được dựa trên các dịch vụ khóa mạnh như CAS (So sánh-Và-Hoán đổi) hoặc các phương thức khác.

0

Không, nó không thực sự đắt tiền. Thông thường chỉ có hai khả năng:

1) Hệ thống có những thứ khác có thể làm: Trong trường hợp này, hệ thống vẫn đang làm việc hữu ích với tất cả các lõi có sẵn.

2) Hệ thống không có gì khác để làm: Trong trường hợp này, chuỗi giữ khóa sẽ được lên lịch. Một hệ thống lành mạnh sẽ không để lại một lõi không được sử dụng trong khi có một luồng sẵn sàng chạy không được lên lịch.

Vì vậy, làm thế nào nó có thể tốn kém? Nếu không có gì khác để hệ thống thực hiện điều đó không yêu cầu lấy khóa đó (hoặc không đủ thứ khác để chiếm tất cả các lõi) và luồng giữ khóa là không phải là sẵn sàng để chạy.Vì vậy, đó là trường hợp bạn phải tránh, và bối cảnh chuyển đổi hoặc vấn đề trước empt không quan trọng (kể từ khi thread sẽ sẵn sàng để chạy).