2012-04-20 29 views
5

Responses to một số "câu trả lời tiềm năng"Killing Infinite Loops trong Java/Clojure

  • Bạn nên rắc "ngắt" vào chủ đề của bạn

    Tôi không viết mã của tôi với mục đích của nó là một vòng lặp dài/vô hạn; nó chỉ là trong phát triển, tôi vô tình viết mã xảy ra là vòng vô hạn, do đó tôi không bao giờ có thể lập kế hoạch trước để đặt "kiểm tra xem chuỗi có bị gián đoạn" vào mã hay không.

Câu hỏi:

Như tôi đã quen thuộc hơn với Java/Clojure/Swank và phát triển mã tăng. Tôi thấy rất dễ dàng khi tôi vô tình viết một hàm clojure kết thúc là một vòng lặp vô hạn - và chạy nó. Điều này sau đó đi trước, và chốt JVM, khiến người hâm mộ trên máy tính xách tay của tôi quay lên - và về cơ bản, tôi phải giết toàn bộ JVM để loại bỏ một chuỗi chạy đi.

Bây giờ, có cách nào tôi có thể bằng cách nào đó giết các chuỗi clojure này một cách an toàn không? Tôi biết rõ rằng Thread.stop có nhiều hậu quả không an toàn (như giữ các khóa mà các chủ đề khác có thể cần, vv ...) - tuy nhiên, đây là các hàm clojure là vòng lặp vô hạn - và tôi đang thực hiện chúng bên ngoài của bất kỳ STM - vì vậy tôi tự hỏi nếu có một số cách để giết các chủ đề một cách an toàn.

Cảm ơn!

+0

Bạn sẽ phải tìm một định nghĩa về vòng lặp vô hạn trước tiên. – Aidanc

+0

(println (dải ô)) là một vòng lặp vô hạn. –

+0

Đó là một ví dụ, không phải là định nghĩa – Jasper

Trả lời

7

Tôi không nghĩ rằng một câu trả lời đầy đủ hoàn chỉnh tồn tại, mặc dù có một số điều không đầy đủ nhưng vẫn hữu ích để làm:

  • Trước tiên tôi nhấn ctrl-c ctrl-c từ repl mà giết thread foreground mà được 99% những lỗi thường gặp của tôi.
  • Sau đó, nếu điều đó không thành công, tôi đi đến thiết bị đầu cuối và lệnh kill.
  • sau đó M-x slime-quit-lisp của nó, clojure-jack-in
+0

Đây không phải là hoàn hảo, nhưng điều này là tốt như tôi tin rằng sẽ được thực tế. –

+0

vì điều này đã được đăng các lệnh chất nhờn thay đổi thành rượu táo, bây giờ nó là cider-jack-in –

0

Về mặt lý thuyết, như đã đề cập trong các ý kiến, đây là một vấn đề rất khó khăn để thực sự giải quyết.

Hy vọng tốt nhất cho một giải pháp thực tế ...

Tôi giả định ở đây là bạn muốn có một cách đáng tin cậy và an toàn hơn giết và hoạt động phân tích trong bài clojure đó đang chạy. . . Và đối với điều này, JPS là con đường để đi, vì JPS giám sát tất cả các quy trình Java, bao gồm mọi thứ bạn làm trong clojure chuẩn.

Tôi luôn sử dụng JPS cho loại điều này, vì nó có thể được sử dụng để hiển thị quá trình tên của các lớp java cụ thể BAO GỒM tên lớp ... Khả năng biết lớp ban đầu gọi một quá trình cung cấp cho bạn một ý tưởng khá chính xác về "những gì" bạn đang thực sự giết chết .

doolittle-5:~ Jpeerindex$ jps -l 
61133 jline.ConsoleRunner 
58998 start.jar 
61161 sun.tools.jps.Jps 
51866 jline.ConsoleRunner 

Trong trường hợp này, vì "Lein repl" (các clojure repl) được bắt đầu qua jline (lớp chính là ConsoleRunner), chúng ta có thể nhìn thấy nó như vậy.

Nếu bạn thực sự cần để xem chi tiết, bạn có thể chọn bất kỳ của các quá trình này và gọi cho họ với jstack:

$> jstack 51866

"Gang nhân # 0 (GC Parallel Chủ đề) "PRIO = 9 tid = 101.802.800 nid = 0x1017f9000 Runnable

"Gang nhân # 1 (GC Parallel Chủ đề)" PRIO = 9 tid = 101.803.800 nid = 0x102301000 Runnable

"đồng thời Mark-Sweep GC Chủ đề" PRIO = 9 tid = 10184e000 nid = 0x1093f0000 Runnable "VM kỳ công tác Chủ đề" PRIO = 10 tid = 1018a4000 nid = 0x10a310000 chờ đợi vào điều kiện

"ngoại lệ Catcher Chủ đề" PRIO = 10 tid = 101.802.000 nid = 0x100704000 Runnable JNI tài liệu tham khảo toàn cầu: 137

trong trường hợp này, bạn sẽ có thể để có được một cảm giác về thời tiết hay không có bất kỳ vấn đề thực tế trong chủ đề của bạn, nhận dạng chúng một cách chính xác, và giết chúng một cách tự tin, v.v ...

2

Điều gì về việc viết macro cho cre ăn những vòng này và macro có thể tiêm mã trong các bước lặp để kiểm tra định kỳ cho một cái gì đó cho biết nó thoát ra khỏi vòng lặp, giống như sự tồn tại của một tệp tạm thời trên/tmp. Vì vậy, về cơ bản để thoát khỏi vòng lặp vô hạn, bạn sẽ chỉ cần tạo tệp tạm thời đó.

+0

Tôi nghĩ đây là giải pháp tốt nhất vì nó không phụ thuộc vào bất kỳ môi trường phát triển cụ thể nào. Bạn có thể thay thế vòng lặp clojure.core tiêu chuẩn/recur với các tùy chỉnh kiểm tra nguyên tử và/hoặc sử dụng bộ đếm hoặc bộ đếm tích hợp để giới hạn vòng lặp và thậm chí có thể hiển thị thông tin gỡ lỗi như trạng thái vòng lặp hiện tại khi nó dừng lại. – optevo

0

Trong Eclipse/ngược chiều kim đồng hồ beta có một tùy chọn để dừng chạy thủ công (ngoài tầm kiểm soát) chủ đề mà không phải dừng REPL. Tôi thích tính năng đó vì cùng lý do bạn muốn có nó.

Nó sử dụng NREPL 0.2.0 beta, tôi nghĩ qua clojure.tools.nrepl.middleware.interruptible-eval. Không chỉ máy khách NREPL 0.2.0 của Eclipse/CCW mà cả phiên bản REPL-y mới nhất cũng hỗ trợ chức năng này (mặc định là CTRL-C để dừng thread, CTRL-D để dừng REPL).