Làm thế nào để Windows biết nếu một chương trình không đáp ứng?


174

Làm thế nào để Windows biết nếu một chương trình không đáp ứng? Nó liên tục bỏ phiếu tất cả các ứng dụng đang chạy?



@ magicandre1981 Trang đó đề xuất một cách để kiểm tra xem chương trình có đang tích cực làm gì đó không, nhưng đó không phải là cách mà Windows thực sự sử dụng.
Kevin Panko

Nhìn vào hàng đợi tin nhắn Windows, một ứng cử viên là hàm PeekMessage ()
Luciano

Câu trả lời:


150

Một ứng dụng nhận các sự kiện từ hàng đợi được cung cấp bởi Windows.

Nếu ứng dụng không thăm dò sự kiện trong một thời gian (5 giây), ví dụ như khi thực hiện một phép tính dài, thì Windows giả định rằng ứng dụng bị treo và cảnh báo cho người dùng.

Để tránh điều đó, các ứng dụng nên đẩy các tính toán đắt tiền đến các luồng công nhân hoặc phân tách xử lý và đảm bảo hàng đợi được bỏ phiếu thường xuyên.


27
↑ Cái này. Không có gì để làm với lịch trình hoặc như được đề xuất trong câu trả lời được chấp nhận, chỉ khi bạn thường xuyên gọi GetMessage(hoặc tương tự) và DispatchMessage.
Damon

1
Câu trả lời được chấp nhận, liên quan đến IsHungAppWindowghi chú chính xác rằng một chương trình trong giai đoạn khởi động không phải gọi GetMessage.
MSalters

@MSalters Với khởi động được xác định là thời gian trước lần đầu tiên GetMessage? Tính năng này cho phép các ứng dụng dòng lệnh đơn giản hoạt động mà không bị coi là treo vì chúng không cần thăm dò hàng đợi.
quái vật ratchet

4
@ratchetfreak: Có lẽ trước cuộc gọi CreatWindow đầu tiên. Các ứng dụng dòng lệnh là những con thú khác nhau hoàn toàn; họ đang chạy bên trong Conhost.EXE và nó tương tác với hệ thống susbystem Windows cho họ.
MSalters

1
Ngoài ra, đối với tôi, trong Windows 7 (và có thể sớm hơn), các cửa sổ sẽ nhận thấy điều này sớm hơn nhiều nếu bạn cố gắng và không thể thao tác với cửa sổ theo một cách nào đó. giống như nếu một chương trình không xử lý tối đa hóa hoặc di chuyển tin nhắn, windows 7 sẽ nhảy sang phải không phản hồi sau khoảng 1 hoặc 2 giây ..
Dave Cousineau

78

Làm thế nào để Windows biết nếu một chương trình không đáp ứng?

Không có mã nguồn cho Windows, chúng ta không thể chắc chắn nó đang làm gì bên trong.

Có một chức năng SDK Windows IsHungAppWindowcó thể được sử dụng.

Một ứng dụng được coi là không phản hồi nếu không chờ đầu vào, không xử lý khởi động và chưa được gọi là PeekMessage trong khoảng thời gian chờ nội bộ là 5 giây.

Nguồn IsHungAppWindow chức năng

Nếu một cửa sổ cấp cao nhất dừng trả lời tin nhắn trong hơn vài giây, hệ thống sẽ coi cửa sổ đó không phản hồi. Trong trường hợp này, hệ thống ẩn cửa sổ và thay thế nó bằng một cửa sổ ma có cùng thứ tự Z, vị trí, kích thước và thuộc tính hình ảnh. Điều này cho phép người dùng di chuyển nó, thay đổi kích thước hoặc thậm chí đóng ứng dụng. Tuy nhiên, đây là những hành động duy nhất có sẵn vì ứng dụng thực sự không đáp ứng.

Nguồn Giới thiệu về Tin nhắn và Hàng đợi Tin nhắn


Nó liên tục bỏ phiếu tất cả các ứng dụng đang chạy?

Không. Ứng dụng không được thăm dò nhưng thời gian xử lý.

Windows có một hệ thống lập lịch cung cấp thời gian xử lý cho các luồng ứng dụng.

Thuật toán lập lịch rất phức tạp và được mô tả đầy đủ trong Windows Internals, Phần 1 (Phiên bản thứ 6) (Tham khảo dành cho nhà phát triển) .


2
Trạng thái treo không dựa trên CPU. Hầu hết các chương trình được "treo" theo nghĩa đó trong 99,999% thời gian và không làm gì cả.
usr

2
@usr Tôi đã nói "treo" ở đâu phụ thuộc vào CPU?
DavidPostill

2
@usr Nửa đầu của câu trả lời là trả lời "Nó có liên tục bỏ phiếu cho tất cả các ứng dụng đang chạy không?". Nửa sau đang trả lời "Làm thế nào Windows biết nếu một chương trình không phản hồi? OP đã hỏi hai câu hỏi trong một;)
DavidPostill

9
Nó không thực sự bỏ phiếu, mặc dù, phải không? Tôi giả sử các bộ phận bên trong giống như một tay cầm chờ trên cửa sổ được báo hiệu khi bạn gọi PeekMessage. Vì vậy, khi Windows gửi tin nhắn đến ứng dụng và không nhận được tín hiệu trong vòng năm giây, nó sẽ đánh dấu ứng dụng là không phản hồi. Và trên thực tế, trên Windows gần đây, cửa sổ chỉ được đánh dấu là "không phản hồi" nếu không đáp ứng kịp thời với đầu vào của người dùng - cho đến khi tôi cố gắng bấm hoặc bấm phím hoặc một cái gì đó, ứng dụng có thể dễ dàng bị "treo" phút mà không "xuất hiện" không đáp ứng.
Luaan

2
Bạn có thể xóa mọi thứ ở trên "Giới thiệu về Tin nhắn và Hàng đợi Tin nhắn" vì nó không giúp trả lời. Windows biết một ứng dụng đã ngừng phản hồi vì nó ngừng bơm tin nhắn. Ứng dụng có thể đang chạy mặc dù nó đang làm một cái gì đó chuyên sâu thay vì bơm tin nhắn (nhưng đó là một chương trình được thiết kế kém).
Andy

32

Trên thực tế, Windows không phải lúc nào cũng biết rằng một ứng dụng không phản hồi. Ứng dụng phải là một ứng dụng tương tác với một cửa sổ và cửa sổ phải nhận được thông báo rằng ứng dụng không xử lý được, trước khi Windows kết luận rằng ứng dụng không phản hồi.

Chẳng hạn, Windows không có cách nào để biết liệu một ứng dụng xử lý số không có giao diện người dùng được chạy từ dòng lệnh đang làm việc của nó hay có thể bị kẹt trong một vòng lặp vô hạn.

Các ứng dụng đồ họa tương tác trong Windows nhận các sự kiện bằng cách liên tục bỏ phiếu hàng đợi tin nhắn. Windows điền vào hàng đợi tin nhắn này với các sự kiện bàn phím, chuột, hẹn giờ, v.v. Nếu một ứng dụng không thăm dò hàng đợi tin nhắn trong một thời gian (5 giây là thời gian chờ được đề cập trong tài liệu chức năng IsHungAppWindow ()), Windows sẽ xem xét ứng dụng "treo", ứng dụng có thể biểu thị bằng cách thay đổi tiêu đề cửa sổ (thêm văn bản " (Không phản hồi) "hoặc văn bản tương đương trong các phiên bản được bản địa hóa) và tô màu nội dung cửa sổ nếu người dùng cố gắng tương tác với cửa sổ.

Các ứng dụng có thể treo theo những cách mà Windows không nhận ra. Chẳng hạn, một ứng dụng có thể tiếp tục bỏ phiếu cho các tin nhắn trong hàng đợi tin nhắn của nó mà không hành động đúng với chúng, vì vậy đối với tất cả các ý định và mục đích thực tế, nó sẽ xuất hiện "treo" mà Windows không nhận ra rằng nó không phản hồi.


8
Không trả lời, theo định nghĩa, có nghĩa là không xử lý các thông báo cửa sổ, do đó, nó không áp dụng cho các dịch vụ hoặc ứng dụng bảng điều khiển và vì vậy tôi sẽ nói Windows luôn biết nếu ứng dụng không phản hồi. Bạn đang nhầm lẫn ổ khóa chết và không phản hồi.
Andy

Tất nhiên nó có thể biết nếu một chương trình không đáp ứng. "Không trả lời" không giống như "bị mắc kẹt trong một vòng lặp vô hạn"
BlueRaja - Danny Pflughoeft

1
Trên thực tế, một ứng dụng có thể truy xuất thư qua GetMessage () và không xử lý chúng và nó sẽ không được Windows công nhận là "không phản hồi" mặc dù thực tế là nó chắc chắn sẽ không phản hồi với người dùng. Thuật ngữ "không phản hồi" cũng thường được sử dụng để mô tả các ứng dụng mạng, dịch vụ, dòng lệnh tương tác, v.v. AFAIK không có định nghĩa chính thức giới hạn cụm từ cho các ứng dụng cửa sổ. Cả bế tắc hoặc vòng lặp vô hạn (hoặc bất kỳ lỗi lập trình nào khác) đều có thể khiến ứng dụng trở nên không phản hồi, nhưng không, tôi không nhầm lẫn giữa nguyên nhân và kết quả.
Viktor Toth

10

Windows là một hệ điều hành, nó giám sát tất cả các chương trình đang chạy.

Windows giao tiếp với các ứng dụng dựa trên cửa sổ bằng các sự kiện. Mỗi chương trình có một luồng liên tục lắng nghe các sự kiện đến và xử lý chúng. Ví dụ: khi bạn nhấp vào nút hoặc biểu tượng vùng thông báo, Windows sẽ tạo sự kiện và đưa nó vào quy trình thích hợp. Quá trình sau đó có thể quyết định làm thế nào để xử lý nó.

Tất cả các tương tác với các chương trình đều dựa trên sự kiện trong Windows, vì vậy khi chương trình không xử lý các sự kiện đến quá lâu, điều đó có nghĩa là nó không phản hồi. Như @DavidPostill đã tìm thấy và ghi chú trong câu trả lời của mình , thời gian chờ là 5 giây. PeekMessagelà chức năng nhận được một sự kiện từ hàng đợi sự kiện.


0

Câu trả lời cho câu hỏi của bạn là có / KHÔNG.

Mặc dù HĐH Windows có thể và thực hiện các ứng dụng thăm dò các sự kiện trong Hàng đợi Nhắn tin của Windows, các chương trình hoàn toàn không có nghĩa vụ liên kết với WinAPI hoặc xử lý / trả lời Hàng đợi Windows. Ngay cả việc trả lời tin nhắn trong Hàng đợi cũng không cho Windows biết chương trình có "bị khóa" hay không. Đó là một chỉ số, nhưng đó là tất cả. Câu trả lời thực sự phức tạp hơn một chút.

Câu trả lời thực sự

Mọi người đang phòng ngừa xung quanh câu trả lời thực tế ở đây. Xác định xem một chương trình "không phản hồi" có phải là một biến thể của " vấn đề tạm dừng " hay không, điều này là không thể giải quyết được trong khoa học máy tính. Giải thích ngắn gọn là bộ xử lý không thể hoạt động như một bên thứ ba tự quan sát để xác định liệu chương trình con có bị kẹt trong một vòng lặp vô hạn hay không, không làm gì so với việc tăng bộ đếm sẽ chấm dứt ở một số số cố định, bình thường. Cả hai điều này có thể được coi là các vòng khép kín. Một dừng lại, khác sẽ không bao giờ chấm dứt. Ngay cả bạn, với tư cách là một người, không biết liệu một chương trình có thực sự đáp ứng hay không, đặc biệt là nếu nó nằm trong một vòng khép kín - bạn chỉ biết nếu nghĩ rằng nó nên (phản hồi).

Từ quan điểm của Windows, cả hai vòng lặp này đều "không đáp ứng" . Đó là lý do tại sao các cửa sổ cho bạn lựa chọn chờ đợi hoặc chấm dứt, bởi vì nó không thể biết được.

Vì vậy, hệ quả là "tại sao các cửa sổ biết rằng một quá trình đang đáp ứng?" Câu trả lời là khá thông minh. Khi một tiến trình được biên dịch trong HĐH đa luồng & đa tiến trình, đôi khi ngay cả trong các vòng lặp được đóng chặt, trình biên dịch có thể thêm vào một lệnhield () , cung cấp một thông báo thuận tiện cho bộ xử lý để nó có thể chuyển sang các tiến trình đang chạy khác . Nó "từ bỏ" bộ xử lý và "chuyển đổi ngữ cảnh" (như được gọi) xảy ra cho phép HĐH (bao gồm Windows) trả lời các sự kiện khác trong ngăn xếp, một số trong đó bao gồm theo dõi quá trình đã phản hồi.

** Điều này không có nghĩa là một quá trình đáp ứng sẽ chấm dứt . ** Một quy trình bên trong một vòng lặp vô hạn có thể mang lại bộ xử lý, cho phép Windows xử lý các sự kiện khác.

Trong một số chương trình windows, chương trình sẽ xử lý các tín hiệu HĐH Windows, có thể cho HĐH biết nó đang "phản hồi", nhưng không có chương trình nào có nghĩa vụ phải làm như vậy. Bạn có thể viết các CPU khá đơn giản, các chương trình không kết thúc ngay cả bên trong các ngôn ngữ cấp cao hơn trên Windows như perl, php, python và Windows có thể không phát hiện ra rằng nó không kết thúc và không phản hồi. Tại thời điểm đó, Windows phụ thuộc vào phương pháp phỏng đoán - tải CPU, bộ nhớ, có bao nhiêu ngắt bộ xử lý được xử lý trong khi chương trình đang chạy để "đoán". Một lần nữa, tại thời điểm đó, Windows phải yêu cầu bạn chấm dứt, bởi vì nó thực sự không biết có nên hay không.

Xem thêm câu trả lời (đúng) của Viktor. Bỏ qua các ý kiến ​​về việc "không trả lời" không giống như một vòng lặp vô hạn. Có tất cả các loại tin nhắn, ngắt, vòng lặp mà một ứng dụng có thể hoặc không thể xử lý mà không thông báo cho hàng đợi tin nhắn Windows. Xử lý hàng đợi tin nhắn chỉ là một trong nhiều loại sự kiện mà HĐH tiếp tục truy cập để cố gắng đoán xem liệu một quy trình có bị treo hay không.

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.