Share via


signal

設定插斷訊號處理。

重要

請勿使用此方法來關閉 Microsoft Store 應用程式,但測試或偵錯案例除外。 根據 Microsoft Store 原則,不允許以程式設計或 UI 方式關閉市集應用程式。 如需詳細資訊,請參閱 UWP 應用程式生命週期

語法

void __cdecl *signal(int sig, int (*func)(int, int));

參數

sig
訊號值。

func
第二個參數是要執行的函式指標。 第一個參數是訊號值,而第二個參數是一個副程式代碼,當第一個參數為 SIGFPE 時可以使用。

傳回值

signal 會傳回與指定訊號相關聯的上一個 func 值。 例如,如果先前的 func 值是 SIG_IGN,則傳回值也會是 SIG_IGN。 傳回值 SIG_ERR 表示錯誤;在該情況下,errno 會設為 EINVAL

如需傳回碼的詳細資訊,請參閱 errno_doserrno_sys_errlist_sys_nerr

備註

signal 函式可讓處理序選擇數種方式中的其中一種來處理來自作業系統的插斷訊號。 自 sig 變數是回應的 signal 中斷;它必須是下列其中一個資訊清單常數,定義于 中 SIGNAL.H

sig 描述
SIGABRT 異常終止
SIGFPE 浮點錯誤
SIGILL 不合法的指令
SIGINT CTRL+C 訊號
SIGSEGV 不合法的儲存體存取
SIGTERM 終止要求

如果 sig 不是上述其中一個值,則會叫用不正確參數處理常式,如參數驗證 中所 定義。 若允許繼續執行,此函式會將 errno 設為 EINVAL,並傳回 SIG_ERR

不論 sig 的值為何,signal 預設都會終止呼叫程式,結束代碼為 3。

注意

任何 Win32 應用程式都不支援 SIGINT。 發生 CTRL+C 插斷時,Win32 作業系統會產生新的執行緒來專門處理該插斷。 這會讓單一執行緒應用程式 (例如 UNIX 中的應用程式) 成為多執行緒,並造成未預期的行為。

func 變數是您寫入的訊號處理常式位址,或是您寫入其中一個預先 定義的訊號動作常數 SIG_DFLSIG_IGN ,亦定義于 SIGNAL.H 中。 如果 func 是函式,則會安裝為指定訊號的訊號處理常式。 訊號處理常式的原型需要一個類型為 int 的正式引數 sig。 作業系統會在插斷時透過 sig 提供實際引數;引數是產生插斷的訊號。 因此,您可以在訊號處理常式中使用上表所列出的六個資訊清單常數,來決定發生何種插斷並採取適當動作。 例如,您可以呼叫 signal 兩次,將相同的處理常式指派給兩個不同的訊號,然後測試處理常式中的 sig 引數,以根據收到的訊號來採取不同的動作。

如果您要測試浮點例外狀況 ( SIGFPE ), func 則指向採用選擇性第二個引數的函式,該引數是表單 FPE_xxxFLOAT.H 定義的數個資訊清單常數之一。 SIGFPE發生訊號時,您可以測試第二個引數的值,以判斷浮點例外狀況的類型,然後採取適當的動作。 此引數和其可能值是 Microsoft 延伸模組。

對於浮點例外狀況,收到訊號時,不會重設 的值 func 。 若要從浮點例外狀況復原,請使用 try/except 子句來括住浮點運算。 您也可以搭配 使用 setjmplongjmp 來復原。 在任一情況下,呼叫處理序都會繼續執行,並且保留處理序浮點狀態的未定義狀態。

如果訊號處理常式傳回,則呼叫進程會緊接在接收中斷訊號的點之後立即繼續執行,而不論訊號或作業模式的類型為何。

執行指定的函式之前,func 的值設為 SIG_DFL。 除非指定 signal 的介入呼叫,否則會針對 SIG_DFL 所述處理下一個插斷訊號。 您可以使用這項功能來重設所呼叫函式中的訊號。

由於訊號處理常式常式通常會在中斷發生時以非同步方式呼叫,所以當執行時間作業不完整且處於未知狀態時,您的訊號處理常式函式可能會取得控制權。 下列清單摘要說明決定可在訊號處理常式中使用之函式的限制。

  • 請勿發出低階或 STDIO.H I/O 常式(例如 printffread )。

  • 請勿呼叫堆積常式或任何使用堆積常式的常式(例如 、 malloc_strdup_putenv )。 如需詳細資訊,請參閱malloc

  • 請勿使用任何產生系統呼叫的函式(例如 或 _getcwdtime )。

  • 除非中斷是由浮點例外狀況所造成,否則請勿使用 longjmp (也就是 sigSIGFPE )。 在此情況下,請先使用 _fpreset 呼叫來重新初始化浮點套件。

  • 請勿使用任何重迭常式。

如果程式是使用 函式來攔截例外狀況, SIGFPE 則程式必須包含浮點程式碼。 如果您的程式沒有浮點程式碼,而且需要執行時間程式庫的訊號處理常式代碼,只要宣告 volatile double 並將它初始化為零:

volatile double d = 0.0f;

SIGILLSIGTERM 訊號不會在 Windows 下產生。 其隨附于 ANSI 相容性。 因此,您可以使用 來設定這些訊號的 signal 訊號處理常式,您也可以呼叫 raise 來明確產生這些訊號。

訊號設定不會保留在呼叫 _exec_spawn 函式所建立的繁衍進程中。 訊號設定會在新處理序中重設為預設值。

需求

常式 必要的標頭
signal <signal.h>

如需相容性詳細資訊,請參閱相容性

範例

下列範例示範如何使用 signal,將一些自訂行為新增至 SIGABRT 訊號。 如需中止行為的詳細資訊,請參閱 _set_abort_behavior

// crt_signal.c
// compile with: /EHsc /W4
// Use signal to attach a signal handler to the abort routine
#include <stdlib.h>
#include <signal.h>

void SignalHandler(int signal)
{
    if (signal == SIGABRT) {
        // abort signal handler code
    } else {
        // ...
    }
}

int main()
{
    typedef void (*SignalHandlerPointer)(int);

    SignalHandlerPointer previousHandler;
    previousHandler = signal(SIGABRT, SignalHandler);

    abort();
}

輸出取決於所使用的執行時間版本、應用程式是主控台或 Windows 應用程式,以及 Windows 登錄設定。 針對主控台應用程式,可能會將類似下列訊息傳送至 stderr:

Debug Error!

Program: c:\Projects\crt_signal\Debug\crt_signal.exe

R6010

- abort() has been called

另請參閱

進程和環境控制
abort
_exec_wexec 函式
exit, _Exit, _exit
_fpreset
_spawn_wspawn 函式