2013-08-25 42 views
14

Nếu tôi nhấn Ctrl + C, điều này sẽ ném một ngoại lệ (luôn nằm trong chuỗi 0?). Bạn có thể nắm bắt điều này nếu bạn muốn - hoặc, nhiều khả năng, chạy một số dọn dẹp và sau đó rethrow nó. Nhưng kết quả bình thường là đưa chương trình dừng lại, bằng cách này hay cách khác.Giết một số nhị phân Haskell

Bây giờ giả sử tôi sử dụng lệnh Unix kill. Khi tôi hiểu nó, kill về cơ bản sẽ gửi một tín hiệu Unix (cấu hình) đến quy trình được chỉ định.

Haskell RTS phản hồi như thế nào? Có tài liệu ở đâu đó không? Tôi sẽ tưởng tượng rằng việc gửi SIGTERM sẽ có tác dụng tương tự như cách nhấn Ctrl + C, nhưng tôi không biết rằng đối với một thực tế ...

(Và dĩ nhiên, bạn có thể sử dụng kill để gửi tín hiệu không có gì để làm với giết chết chút nào. Một lần nữa, tôi sẽ tưởng tượng rằng RTS sẽ bỏ qua, nói rằng, SIGHUP hoặc SIGPWR, nhưng tôi không biết chắc chắn.)

+3

Ctrl-C gửi 'SIGINT'. Tôi mong đợi 'SIGTERM' được xử lý khác với' SIGINT'. –

+2

Tôi nghĩ rằng có một hành động mặc định cho tất cả các tín hiệu được xác định bởi Posix và/hoặc hệ thống cụ thể, xem tại đây: http://man7.org/linux/man-pages/man7/signal.7.html (Cuộn xuống bàn). – bennofs

+1

@bennofs Điều cần biết. Hành động mặc định cho 'SIGINT' dường như là chấm dứt quá trình, nhưng RTS xử lý rõ ràng đặc biệt này. Nó sẽ là tốt đẹp để biết nếu bất kỳ tín hiệu khác nhận được xử lý đặc biệt ... – MathematicalOrchid

Trả lời

12

Đang tìm kiếm các "tín hiệu" trong ghc source code trên github tiết lộ installDefaultSignals chức năng:

void 
initDefaultHandlers(void) 
{ 
    struct sigaction action,oact; 

    // install the SIGINT handler 
    action.sa_handler = shutdown_handler; 
    sigemptyset(&action.sa_mask); 
    action.sa_flags = 0; 
    if (sigaction(SIGINT, &action, &oact) != 0) { 
sysErrorBelch("warning: failed to install SIGINT handler"); 
    } 

#if defined(HAVE_SIGINTERRUPT) 
    siginterrupt(SIGINT, 1); // isn't this the default? --SDM 
#endif 

    // install the SIGFPE handler 

    // In addition to handling SIGINT, also handle SIGFPE by ignoring it. 
    // Apparently IEEE requires floating-point exceptions to be ignored by 
    // default, but alpha-dec-osf3 doesn't seem to do so. 

    // Commented out by SDM 2/7/2002: this causes an infinite loop on 
    // some architectures when an integer division by zero occurs: we 
    // don't recover from the floating point exception, and the 
    // program just generates another one immediately. 
#if 0 
    action.sa_handler = SIG_IGN; 
    sigemptyset(&action.sa_mask); 
    action.sa_flags = 0; 
    if (sigaction(SIGFPE, &action, &oact) != 0) { 
    sysErrorBelch("warning: failed to install SIGFPE handler"); 
} 
#endif 

#ifdef alpha_HOST_ARCH 
    ieee_set_fp_control(0); 
#endif 

    // ignore SIGPIPE; see #1619 
    // actually, we use an empty signal handler rather than SIG_IGN, 
    // so that SIGPIPE gets reset to its default behaviour on exec. 
    action.sa_handler = empty_handler; 
    sigemptyset(&action.sa_mask); 
    action.sa_flags = 0; 
    if (sigaction(SIGPIPE, &action, &oact) != 0) { 
sysErrorBelch("warning: failed to install SIGPIPE handler"); 
    } 

    set_sigtstp_action(rtsTrue); 
} 

Từ đó, bạn có thể thấy rằng GHC cài đặt ít nhất SIGINT và SIGPIPE xử lý. Tôi không biết nếu có bất kỳ xử lý tín hiệu khác ẩn trong mã nguồn.

+2

Làm tốt lắm. Vì vậy, có vẻ như 'SIGINT' là tín hiệu duy nhất có xử lý đặc biệt ... – MathematicalOrchid

16

Googling "haskell bắt SIGTERM" dẫn tôi đến System.Posix.Signals của gói unix, có hệ thống tìm kiếm khá tốt đẹp để bắt và xử lý các tín hiệu này. Chỉ cần cuộn xuống phần "Xử lý tín hiệu".

EDIT: Một ví dụ nhỏ:

import System.Posix.Signals 
import Control.Concurrent (threadDelay) 
import Control.Concurrent.MVar 

termHandler :: MVar() -> Handler 
termHandler v = CatchOnce $ do 
    putStrLn "Caught SIGTERM" 
    putMVar v() 

loop :: MVar() -> IO() 
loop v = do 
    putStrLn "Still running" 
    threadDelay 1000000 
    val <- tryTakeMVar v 
    case val of 
     Just _ -> putStrLn "Quitting" >> return() 
     Nothing -> loop v 

main = do 
    v <- newEmptyMVar 
    installHandler sigTERM (termHandler v) Nothing 
    loop v 

Chú ý rằng tôi đã phải sử dụng một MVAr để thông báo cho loop rằng đó là thời gian để bỏ thuốc lá. Tôi đã thử sử dụng exitSuccess từ System.Exit, nhưng kể từ khi termHandler thực hiện trong một chuỗi không phải là chủ đề chính, nó không thể khiến chương trình thoát. Có thể có một cách dễ dàng hơn để làm điều đó, nhưng tôi chưa bao giờ sử dụng mô-đun này trước đây vì vậy tôi không biết một. Tôi đã thử nghiệm điều này trên Ubuntu 12.10.

+1

Thư viện này trông rất có liên quan nếu tôi thực sự cần ghi đè các hành động mặc định. Tôi vẫn muốn biết những gì mặc định là mặc dù. ;-) – MathematicalOrchid

+0

Sai lầm của tôi. Nhìn vào nguồn của mô-đun đó cũng không cho tôi biết nhiều. Tôi đã thử một số tín hiệu khác nhau và có vẻ như hành động mặc định khi bất kỳ hành động nào trong số này được gửi đến quy trình đó là chỉ dừng quá trình. – bheklilr

+1

Không cần phải xin lỗi; thông tin của bạn chắc chắn sẽ hữu ích. – MathematicalOrchid

Các vấn đề liên quan