Làm thế nào để ngủ một chủ đề làm việc?


14

Khi bạn ngủ một chủ đề, những gì đang thực sự xảy ra?

Tôi thấy rằng ngủ một chủ đề "tạm dừng chủ đề hiện tại trong một khoảng thời gian nhất định" . Nhưng nó hoạt động như thế nào?

Theo cách thức Thread.s ngủ () hoạt động nội bộThread.s ngủ thực sự hoạt động như thế nào? :

  • thời gian ngủ sẽ phải chịu một số chi tiết cụ thể của hệ thống
  • giấc ngủ bị chặn
  • luồng ra khỏi CPU và dừng thực thi
  • luồng không tiêu tốn thời gian CPU trong khi ngủ

Tôi hoàn toàn không thể hiểu được các cơ chế bên trong và cơ bản của tất cả những điều này có nghĩa là gì.

Tôi hiểu rằng có một cái gì đó được gọi là bộ lập lịch chịu trách nhiệm chuyển đổi giữa các luồng.

Các nguồn dường như chỉ ra rằng điều này thay đổi tùy theo HĐH (hoặc phần cứng?) Và hầu hết các luồng được đưa ra 1ms - 60ms hoặc lâu hơn để thực hiện một số hành động trước khi CPU chuyển sang luồng khác.

Nhưng khi một luồng ngủ (ví dụ, nhiều giây), làm thế nào để nó tiếp tục? Tôi đoán một bộ đếm thời gian có liên quan bằng cách nào đó, nó có phải là đồng hồ của bo mạch chủ? Có liên quan đến tốc độ xung nhịp CPU?

Và ngay cả khi có liên quan đến bộ đếm thời gian, làm thế nào CPU biết khi nào cần chú ý đến luồng một lần nữa? Nó sẽ không phải liên tục kiểm tra chủ đề để xem nó đã sẵn sàng chưa? Đó không phải là bỏ phiếu hiệu quả và do đó loại đang tiêu tốn thời gian của CPU?

Là ngủ một ngôn ngữ cụ thể theo chủ đề hay HĐH chịu trách nhiệm cho nó hay nó là một thứ dành riêng cho CPU?

Ai đó vui lòng giải thích điều này cho tôi với những giải thích cơ bản về những thứ như bộ lập lịch và CPU đang làm gì trong tất cả những điều này?


2
Đánh thức một luồng ngủ một lần nữa hoạt động bằng các ngắt thời gian, thường được tạo bởi đồng hồ ngắt, là thành phần phần cứng tách biệt với phần lõi của CPU xử lý các hướng dẫn. Điều đó tránh được nhu cầu bỏ phiếu. Có lẽ lời giải thích này trên Quora sẽ làm rõ một số điều: quora.com/How-does-threading-work-at-CPU-level
Doc Brown

1
Hầu hết các JVM không thực sự triển khai đa luồng: Tất cả những gì họ làm là sử dụng các khả năng đa luồng của hệ điều hành bên dưới. Nếu bạn thực sự muốn biết làm thế nào nó hoạt động, có rất nhiều sách về chủ đề thiết kế hệ điều hành.
Solomon chậm

Câu trả lời:


11

Có nhiều thứ liên quan đến việc chạy một chương trình hơn là chỉ mã trong chương trình đó.

Bất kỳ chương trình nào chạy trong HĐH đa tiến trình đều nằm dưới sự kiểm soát của bộ lập lịch của HĐH và bộ lập lịch sẽ duy trì một bảng rõ ràng cho biết quá trình nào đang chạy, chương trình nào đang chờ để chạy khi có chu kỳ CPU và thậm chí không có cố gắng chạy (ngủ). Bộ lập lịch thường gán các lát thời gian có kích thước bằng nhau cho các quy trình tùy thuộc vào mức độ ưu tiên và lịch sử thực hiện của chúng. Cuối cùng, vòng lặp này được điều khiển bởi các ngắt phần cứng, thường được tạo bởi bộ tạo dao động trên bo mạch chính.

Ngủ luôn là một tính năng mà ngôn ngữ lập trình chỉ có thể hỗ trợ vì môi trường thời gian chạy nơi nó sẽ được thực thi hỗ trợ nó. Một chương trình bình thường không thể ngừng bản thân , nó chỉ có thể nói với các lịch trình nó như thế nào sẽ thích được đối xử - và lên lịch là không có nghĩa là nghĩa vụ hay thậm chí là luôn luôn có khả năng đáp ứng mong muốn đó. Hãy nghĩ về một máy tính xách tay bị đóng cửa và đi vào giấc ngủ đông; bộ tạo dao động của bo mạch chính vẫn giữ nhịp đập, nhưng vì bộ lập lịch không chạy, nên không có quá trình nào có thể chạy dù mức độ ưu tiên của nó cao đến đâu.


Điều này (nói chung) đúng với các quy trình, nhưng không phải lúc nào cũng đúng với các luồng, đôi khi phụ thuộc vào ngôn ngữ. Các chủ đề có thể được thực hiện độc lập với HĐH và có thể hợp tác hoặc phòng ngừa. Ví dụ: Ruby có "sợi" (ngoài các luồng). Sợi Ruby được lên lịch hợp tác.
david25272

Đúng, chỉ chủ đề bản địa làm việc như thế này. Các luồng màu xanh lá cây được lên lịch bởi VM thực thi một chương trình bằng ngôn ngữ được biên dịch byte. Thông thường chúng được sử dụng khi các luồng gốc không có sẵn hoặc khi chạy mã không an toàn theo luồng (đôi khi VM có thể đảm bảo rằng ngữ nghĩa của chương trình đa luồng vẫn đúng theo cách mà bộ lập lịch hệ điều hành không thể).
Kilian Foth

7

Như Doc Brown đã đề cập trong một bình luận, ngắt là chìa khóa, và không chỉ để ngủ.

Ngắt là một tín hiệu phần cứng rằng bộ xử lý sẽ dừng những gì nó đang làm và chạy một đoạn mã. Thiết bị bên ngoài kích hoạt ngắt khi chúng cần sự chú ý của bộ xử lý: ví dụ: khi đĩa đã đọc xong dữ liệu hoặc phím được nhấn hoặc đồng hồ đếm ngược trên bo mạch chủ đã về không.

Mã xử lý ngắt thường rất nhỏ và rất nhanh. Ví dụ, khi đĩa biểu thị một khối đã được sao chép vào bộ nhớ, HĐH có thể chỉ cần ghi lại thực tế đó vào danh sách "các khối sẵn sàng" ở đâu đó và sau đó quay lại bất cứ thứ gì nó đang làm. Bạn không muốn CPU dành toàn bộ thời gian cho mã xử lý ngắt và không chạy mã người dùng.

Một đoạn mã điều khiển ngắt không nhất thiết phải nhỏ là bộ lập lịch. Nó được kích hoạt bởi tín hiệu từ đồng hồ đếm ngược và kiểm tra trạng thái của hệ thống bất cứ khi nào nó chạy. Điều này thường sẽ bao gồm xác định các quy trình đã sẵn sàng để chạy (ví dụ: vì khối mà chúng đang chờ đã xuất hiện trong bộ nhớ), cũng như các quy trình đã cạn kiệt thời gian của chúng.

Vì vậy, khi bạn thực hiện một luồng ngủ, điều bạn đang làm là nói với HĐH rằng (1) bạn đang từ bỏ lát cắt thời gian của mình và (2) bạn không nên thức dậy nữa cho đến khi một thời gian nhất định trôi qua.

Bất cứ khi nào trình lập lịch chạy, nó sẽ nhìn vào luồng của bạn và chỉ đánh dấu nó là "sẵn sàng để chạy" nếu thời gian đó trôi qua. Đây là một cuộc bỏ phiếu, nhưng đây không phải là cuộc bỏ phiếu "vòng lặp bận rộn" vì nó được kích hoạt bởi một ngắt. Nó cũng không đắt lắm: thông thường chỉ có một ngàn hoặc nhiều luồng chạy cùng một lúc.

Điều này cũng sẽ cung cấp cho bạn một ý tưởng tại sao thời gian ngủ không chính xác: khi luồng của bạn sẵn sàng để chạy, có thể có các luồng khác vẫn đang chạy và chưa hết thời gian của chúng. Hoặc có thể có các luồng ưu tiên cao hơn đã sẵn sàng để chạy.


Đây là cách hệ điều hành "hiện đại" hoạt động. Trong các hệ điều hành cũ hơn, chẳng hạn như Windows 3 hoặc Mac OS trước OS X, một quy trình phải nhường quyền điều khiển () cho hệ điều hành. Thật không may nếu một chương trình bị mắc kẹt trong một vòng lặp hoặc bế tắc bằng cách nào đó, nó có thể không bao giờ mang lại quyền kiểm soát và toàn bộ hệ thống sẽ bị treo.
david25272

@ david25272 - Tôi nghĩ rằng tôi sẽ sử dụng từ "đơn giản hơn" thay vì "cũ hơn" vì có những hệ thống từ những năm 1960 đã thực hiện đa nhiệm được ưu tiên. Và mặc dù sự thật là đa nhiệm hợp tác đòi hỏi luồng hoạt động phải làm gì đó để giải phóng quyền kiểm soát bộ xử lý của nó (thông thường bằng cách thực hiện cuộc gọi hệ thống chặn, thay vì năng suất rõ ràng), tôi không tin rằng có nhiều lập trình viên đa năng ngày nay, những người sử dụng một hệ điều hành với một mô hình luồng hợp tác.
kdgregory
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.