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


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


171
2017-08-24 07:33


gốc


fastupandwait.io/blog/detecting-a-hung-windows-process - magicandre1981
@ magicandre1981 Trang đó đề xuất một cách để kiểm tra xem một chương trình đang tích cực làm điều gì đó, nhưng nó không phải là cách 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ác câu trả lời:


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

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

Để tránh các ứng dụng đó nên đẩy các tính toán tốn kém đến các chuỗi công việc hoặc chia nhỏ quá trình xử lý và đảm bảo hàng đợi được kiểm tra thường xuyên.


149
2017-08-24 10:09



↑ 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ỉ cho dù bạn thường xuyên gọi GetMessage (hoặc tương tự) và DispatchMessage. - Damon
Câu trả lời được chấp nhận, đề cập đến IsHungAppWindow ghi 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 Khi khởi động được định nghĩa là thời gian trước 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. - ratchet freak
@ratchetfreak: Có lẽ trước cuộc gọi CreateWindow đầu tiên. Ứng dụng dòng lệnh là những con thú khác nhau hoàn toàn; chúng đang chạy bên trong ConHost.EXE và nó tương tác với hệ điều hành GUI của Windows cho chúng. - MSalters
Ngoài ra, có vẻ như với tôi rằng 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 thao túng cửa sổ theo một cách nào đó. như nếu một chương trình không xử lý thông điệp tối đa hoặc di chuyển, cửa sổ 7 sẽ nhảy ngay để không phản hồi sau khoảng 1 hoặc 2 giây .. - Dave Cousineau


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

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

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

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

Nguồn Hàm IsHungAppWindow

Nếu cửa sổ cấp cao nhất dừng trả lời thư trong hơn vài giây, hệ thống sẽ xem 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 cửa sổ ma có cùng thứ tự Z, vị trí, kích thước và thuộc tính trực quan. Đ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 phản hồi.

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


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

Không. Các ứng dụng không được thăm dò nhưng được cung cấp thời gian xử lý.

Windows có một hệ thống lập kế hoạ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 biểu phức tạp và được mô tả đầy đủ trong Windows Internals, Phần 1 (Phiên bản thứ 6) (Tham chiếu của nhà phát triển).


78
2017-08-24 08:48



Trạng thái treo không dựa trên CPU. Hầu hết các chương trình đều "treo" theo nghĩa đó với 99.999% thời gian và không làm gì cả. - usr
@usr Tôi đã nói rằng "treo" phụ thuộc vào CPU ở đâu? - DavidPostill♦
@usr Nửa đầu của câu trả lời là trả lời "Liệu nó có liên tục tiếp tục bỏ phiếu cho tất cả các ứng dụng đang chạy không?". Phần thứ hai là trả lời "Làm thế nào để Windows biết nếu một chương trình không đáp ứng ?. OP hỏi hai câu hỏi trong một;) - DavidPostill♦
Nó không thực sự bỏ phiếu, mặc dù, là nó? Tôi cho rằng các bộ phận bên trong giống như một tay cầm chờ đợi 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 hơn, cửa sổ chỉ được đánh dấu là "không phản hồi" nếu nó không phản hồi người dùng đầu vào trong thời gian - cho đến khi tôi cố gắng bấm hoặc nhấn một phím hoặc một cái gì đó, ứng dụng có thể dễ dàng ở lại "treo" trong vài phút mà không "xuất hiện" không đáp ứng. - Luaan
Bạn có thể xóa tất cả 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 được câu trả lời. Windows biết một ứng dụng đã ngừng đáp ứng vì nó ngừng bơm tin nhắn. Các ứng dụng có thể chạy mặc dù nó 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 thiết kế kém). - Andy


Trên thực tế, Windows không phải lúc nào cũng biết rằng ứ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ác thông báo mà ứ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.

Ví dụ, Windows không có cách nào để biết nếu một ứng dụng crunching 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ó, hoặc có lẽ bị mắc 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 một hàng đợi tin nhắn. Windows sẽ điền hàng đợi tin nhắn này với các sự kiện bàn phím, chuột, hẹn giờ, vv. Nếu một ứng dụng không thăm dò hàng đợi tin nhắn một thời gian (5 giây là thời gian chờ được đề cập trong tài liệu hàm IsHungAppWindow ()), Windows sẽ xem xét ứng dụng "treo", nó có thể chỉ ra bằng cách thay đổi tiêu đề cửa sổ (thêm văn bản " (Không trả lờ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ô xám 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. Ví dụ, 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 cách, vì vậy cho tất cả các ý định thực tế và mục đích nó sẽ xuất hiện "treo" mà Windows không nhận ra rằng nó không đáp ứng.


32
2017-08-24 11:12



Không trả lời, theo định nghĩa, có nghĩa là không xử lý tin nhắn cửa sổ, vì vậy nó không áp dụng cho các dịch vụ hoặc ứng dụng giao diện điều khiển, và vì vậy tôi muốn nói Windows luôn biết nếu ứng dụng không phản hồi. Bạn đang bối rối những ổ khóa chết và không đáp ứng. - Andy
Tất nhiên nó có thể biết nếu một chương trình không đáp ứng. "Không phản hồi" không giống như "bị kẹt trong vòng lặp vô hạn" - BlueRaja - Danny Pflughoeft
Trên thực tế, một ứng dụng có thể truy xuất các tin nhắn thông qua GetMessage () và không xử lý chúng, và nó sẽ không được Windows nhận ra là "không phản hồi" mặc dù thực tế nó sẽ xuất hiện không đáp ứng với người dùng của nó. Thuật ngữ "không trả lời" cũng thường được sử dụng để mô tả mạng, dịch vụ, dòng lệnh tương tác, vv các ứng dụng; AFAIK không có định nghĩa chính thức để giới hạn cụm từ đối với 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) có thể khiến ứng dụng trở nên không đáp ứng, nhưng không, tôi không nhầm lẫn nguyên nhân và hiệu ứng. - Viktor Toth


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 một nút hoặc biểu tượng khu vực thông báo, Windows sẽ tạo một sự kiện và đưa nó vào quy trình thích hợp. Quá trình này sau đó có thể quyết định cách 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ý sự kiện đến quá lâu, điều đó có nghĩa là chương trình không phản hồi. Vì @DavidPostill đã tìm thấy và ghi chú trong câu trả lời của anh ấy, thời gian chờ là 5 giây. PeekMessage là hàm nhận sự kiện từ hàng đợi sự kiện.


10
2017-08-24 09:00





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

Trong khi hệ điều hành Windows có thể và thực hiện các ứng dụng thăm dò ý kiến ​​với các sự kiện trong Hàng đợi Nhắn tin 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 một tin nhắn trong Hàng đợi cũng không nói cho Windows biết chương trình có "bị khóa" hay không. Đó là một chỉ báo, nhưng đó là tất cả. Câu trả lời thực sự khá phức tạp hơn một chút.

Câu trả lời thực

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

Từ quan điểm của Windows, cả hai vòng lặp này đều là "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ể nói.

Vậy hệ quả là "tại sao cửa sổ lại biết rằng một quá trình  Khi một quá trình được biên dịch trong một hệ điều hành đa luồng và đa tiến trình, đôi khi ngay cả trong các vòng khép kín chặt chẽ, trình biên dịch có thể thêm vào một yield () lệnh, cung cấp một thông báo thuận tiện cho bộ xử lý mà 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" (được gọi là) xảy ra cho phép hệ điều hành (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  đã trả lời.

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

Trong một số chương trình cửa sổ, chương trình sẽ xử lý tín hiệu hệ điều hành Windows, có thể cho hệ điều hành biết là "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 khá đơn giản CPU hogging, không chấm dứt chương trình ngay cả 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 chấm dứt và không đáp ứng. Tại thời điểm đó, Windows phụ thuộc vào chẩn đoán - CPU tải, bộ nhớ, bao nhiêu ngắt 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 nếu nó cần.

Xem thêm câu trả lời của Viktor (đúng). Bỏ qua các nhận xét về việc liệu "không phản hồ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 cần 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ệ điều hành tiếp tục truy cập để cố gắng phỏng đoán cho dù một quá trình được treo.


0
2018-03-14 02:57