IT이야기

신호와 신호의 차이점은 무엇입니까?

cyworld 2022. 7. 25. 22:43
반응형

신호와 신호의 차이점은 무엇입니까?

되었습니다.sigaction()하다는 려했했 i를 .signal() . 을 사용해야 .sigaction()처음부터 글씨를 쓰고 있다면 어떤 것을 선택해야 할까요?

특별한 이유가 없는 한 사용하세요.

인터페이스는 오래된 것(따라서 가용성)을 가지고 있으며 C 표준에 정의되어 있습니다.그럼에도 불구하고, 그것은 많은 바람직하지 않은 특성을 가지고 있다.sigaction()- 에 하지 한sigaction()을 할 수 있게 .signal()★★★★★★ 。

  1. signal()에 다른 하지 않습니다.즉, "Current Handler"가 실행되고 있는 동안 다른 신호가 도착하는 것을 차단하지 않습니다.sigaction()는 현재 핸들러가 반환될 때까지 다른 신호를 차단할 수 있습니다.
  2. signal()function을 function(기능)으로 .SIG_DFL이데올로기 때문에은, 「」, 「」가, 「」가signal()핸들러는, 그 최초의 액션으로서 재인스톨 할 필요가 있습니다., 되는 에, 이 창에서는 인스턴스가, advantive - core dump이 발생합니다.nate, advidant - core dump)을 사용합니다.
  3. ★★★★★★★★★★★★★★의 정확한 동작signal()시스템마다 다르며, 표준에서는 이러한 차이를 허용하고 있습니다.

으로 사용하기에 가 됩니다.sigaction()signal() 「」의 「」입니다.sigaction()더 안절부절못한다는 건 부인할 수 없죠

어느 쪽을 사용하든 , 및 등 대체 신호 인터페이스에 현혹되지 않도록 하십시오.그들은 명목상 에 대한 대체 수단이다.sigaction()그러나 POSIX에는 거의 표준화되어 있지 않으며 심각한 사용이 아닌 하위 호환성을 위해 포함되어 있습니다.POSIX 규격에서는 멀티 스레드 프로그램에서의 동작은 정의되어 있지 않습니다.

멀티 스레드 프로그램과 신호는 전혀 다른 복잡한 이야기입니다.멀티 스레드 애플리케이션에서는 AFAIK, 및 둘 다 OK입니다.

옥수수 줄기는 다음을 관찰합니다.

의 Linux man 페이지에 다음과 같이 표시됩니다.

  멀티 스레드 프로세스에서의 효과는 지정되지 않았습니다.

저는 이렇게 합니다.sigaction()멀티 스레드 프로세스에서 안전하게 사용할 수 있는 유일한 방법입니다.

신기하네요.이 경우 Linux 설명서 페이지는 POSIX보다 더 제한적입니다.POSIX는 다음을 지정합니다.

프로세스가 멀티 스레드인 경우 또는 프로세스가 싱글 스레드이고 신호 핸들러가 실행되는 경우 다음 결과 이외의 경우:

  • 「」를 호출하는 .abort(),raise(),kill(),pthread_kill() , 「」sigqueue()되지 않은
  • 차단 해제된 콜이 반환되기 전에 보류 중인 신호가 차단 해제되어 전달됨

핸들러가 '' 이외의 오브젝트를 , 되어 있지 .errno다음과 같이 선언된 개체에 값을 할당하는 것 이외에는 정적 스토리지 기간을 사용합니다.volatile sig_atomic_t또는 신호 핸들러가 신호 개념에 기재되어 있는 함수 중 하나 이외의 함수를 호출하는 경우.

는 'POSIX'의을 명확하게 명시하고 있습니다.signal()멀티패키지 어플리케이션에서 사용할 수 있습니다.

그럼에도 불구하고,sigaction()으로 모든는 '멀티캐릭터 코드'를 사용해야 .또한 휴대용 멀티캐리어 코드는sigaction()할 수 없는 압도적인 이유가 없는 한(예를 들어 "표준 C에서 정의된 함수만 사용" 등) C11 코드는 멀티 스레드화할 수 있습니다.기본적으로 이 답변의 첫 단락에도 나와 있습니다.

요컨대:

sigaction()는 양호하고 명확하게 정의되어 있지만 Linux 기능이기 때문에 Linux에서만 동작합니다. signal()는 불량하고 정의가 불충분하지만 C 표준 함수이기 때문에 어떤 경우에도 동작합니다.

Linux의 man 페이지에서는 뭐라고 합니까?

man 2 signal(온라인 참조) 상태:

signal버전에 signal()의 다른 .피하다: 사용하다: 사용하다sigaction(2) 。아래의 「을 참조해 주세요.이치노

이식성 signal()의 유일한 휴대용 용도는 신호의 디스포지션을 SIG_DFL 또는 SIG_IGN으로 설정하는 것입니다.signal()을 사용하여 시그널핸들러를 확립할 때의 의미는 시스템마다 다릅니다(POSIX.1은 이 변경을 명시적으로 허가합니다).이 목적을 위해서 사용하지 말아 주세요.

「」, 「」는 하지 말아 주세요signal()을 사용하다sigaction()대!!

GCC의 생각은?

호환성 주의:상술한 바와 같이signal이 기능은 가능하면 피해야 합니다. sigaction권장되는 방법입니다.

출처 : https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling

"Linux" GCC를 하지 signal(), 를 하려면 , 「」, 「」를 사용합니다sigaction() 이 혼란스러운 것을 인가 하는 : 이 스러운 것을 어떻게 할 것인가?sigaction()가!!?

사용 예:

Excellent GCC를 읽다signal()예: https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling

그들의 ★★★★★★★★★★★★★★★★★★★★★★★★★.sigaction()예: https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html

그 '아까부터', '아까부터', '아까부터', '아까부터'라는 방법이 .sigaction():

1. sigaction()위에서 설명한 바와 같이 신호 핸들러를 올바르게 접속하는 방법이기 때문에 다음과 같습니다.

#include <errno.h>  // errno
#include <signal.h> // sigaction()
#include <stdio.h>  // printf()
#include <string.h> // strerror()

#define LOG_LOCATION __FILE__, __LINE__, __func__ // Format: const char *, unsigned int, const char *
#define LOG_FORMAT_STR "file: %s, line: %u, func: %s: "

/// @brief      Callback function to handle termination signals, such as Ctrl + C
/// @param[in]  signal  Signal number of the signal being handled by this callback function
/// @return     None
static void termination_handler(const int signal)
{
    switch (signal)
    {
    case SIGINT:
        printf("\nSIGINT (%i) (Ctrl + C) signal caught.\n", signal);
        break;
    case SIGTERM:
        printf("\nSIGTERM (%i) (default `kill` or `killall`) signal caught.\n", signal);
        break;
    case SIGHUP:
        printf("\nSIGHUP (%i) (\"hang-up\") signal caught.\n", signal);
        break;
    default:
        printf("\nUnk signal (%i) caught.\n", signal);
        break;
    }

    // DO PROGRAM CLEANUP HERE, such as freeing memory, closing files, etc.

    
    exit(signal);
}

/// @brief      Set a new signal handler action for a given signal
/// @details    Only update the signals with our custom handler if they are NOT set to "signal ignore" (`SIG_IGN`),
///             which means they are currently intentionally ignored. GCC recommends this "because non-job-control
///             shells often ignore certain signals when starting children, and it is important for children
///             to respect this." See
///             https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling
///             and https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html.
///             Note that termination signals can be found here:
///             https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html#Termination-Signals
/// @param[in]  signal  Signal to set to this action
/// @param[in]  action  Pointer to sigaction struct, including the callback function inside it, to attach to this signal
/// @return     None
static inline void set_sigaction(int signal, const struct sigaction *action)
{
    struct sigaction old_action;

    // check current signal handler action to see if it's set to SIGNAL IGNORE
    sigaction(signal, NULL, &old_action);
    if (old_action.sa_handler != SIG_IGN)
    {
        // set new signal handler action to what we want
        int ret_code = sigaction(signal, action, NULL);
        if (ret_code == -1)
        {
            printf(LOG_FORMAT_STR "sigaction failed when setting signal to %i;\n"
                   "  errno = %i: %s\n", LOG_LOCATION, signal, errno, strerror(errno));
        }
    }
}

int main(int argc, char *argv[])
{
    //...

    // Register callbacks to handle kill signals; prefer the Linux function `sigaction()` over the C function
    // `signal()`: "It is better to use sigaction if it is available since the results are much more reliable."
    // Source: https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling
    // and https://stackoverflow.com/questions/231912/what-is-the-difference-between-sigaction-and-signal/232711#232711.
    // See here for official gcc `sigaction()` demo, which this code is modeled after:
    // https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html

    // Set up the structure to specify the new action, per GCC's demo.
    struct sigaction new_action;
    new_action.sa_handler = termination_handler; // set callback function
    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = 0;

    // SIGINT: ie: Ctrl + C kill signal
    set_sigaction(SIGINT, &new_action);
    // SIGTERM: termination signal--the default generated by `kill` and `killall`
    set_sigaction(SIGTERM, &new_action);
    // SIGHUP: "hang-up" signal due to lost connection
    set_sigaction(SIGHUP, &new_action);

    //...
}

. 2. 리리고 2signal()위에서 설명한 바와 같이 신호 핸들러를 연결하는 방법은 좋지 않지만 사용 방법을 아는 것은 좋습니다.

다음은 GCC 데모 코드 복사 붙여넣기입니다.최고의 성능을 발휘합니다.

#include <signal.h>

void
termination_handler (int signum)
{
  struct temp_file *p;

  for (p = temp_file_list; p; p = p->next)
    unlink (p->name);
}

int
main (void)
{
  …
  if (signal (SIGINT, termination_handler) == SIG_IGN)
    signal (SIGINT, SIG_IGN);
  if (signal (SIGHUP, termination_handler) == SIG_IGN)
    signal (SIGHUP, SIG_IGN);
  if (signal (SIGTERM, termination_handler) == SIG_IGN)
    signal (SIGTERM, SIG_IGN);
  …
}

주목해야 할 주요 링크:

  1. 표준 신호: https://www.gnu.org/software/libc/manual/html_node/Standard-Signals.html#Standard-Signals
  2. 종료 신호: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html#Termination-Signals
  3. GCC를 인 처리signal()사용 예: https://www.gnu.org/software/libc/manual/html_node/Basic-Signal-Handling.html#Basic-Signal-Handling
  4. GCC © GCCsigaction()사용 예: https://www.gnu.org/software/libc/manual/html_node/Sigaction-Function-Example.html
  5. 를 포함한 세트sigemptyset() ★★★★★★★★★★★★★★★★★」sigfillset()아직 정확하게는 모르지만, 중요한 것은 알고 있습니다.https://www.gnu.org/software/libc/manual/html_node/Signal-Sets.html

다음 항목도 참조하십시오.

  1. 실행 중인 프로세스에 신호를 수동으로 보내는 방법 및 프로그램에서 신호를 트랩하는 방법(예: Bash)에 대한 답변입니다.
  2. TutorialsPoint C++ 신호 처리 [뛰어난 데모 코드 사용]:https://www.tutorialspoint.com/cplusplus/cpp_signal_handling.htm
  3. https://www.tutorialspoint.com/c_standard_library/signal_h.htm

아래 행은 다음과 같은 결정을 내리기에 충분했습니다.

sigaction() 함수는 보다 포괄적이고 신뢰성 높은 신호 제어 메커니즘을 제공합니다.새로운 어플리케이션에서는 signal()이 아닌 sigaction()을 사용해야 합니다.

http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html#tag_03_690_07

처음부터 시작하든, 오래된 프로그램을 수정하든 시그니처가 올바른 옵션이어야 합니다.

OS의 신호 설비를 위한 다른 인터페이스입니다.signal()은 구현 정의(종종 레이스에 취약한) 동작을 가지며 Windows, OS X, Linux 및 기타 UNIX 시스템에서 다르게 동작하기 때문에 가능하면 시그널링에 시그널을 사용하는 것이 좋습니다.

자세한 내용은 이 보안 노트를 참조하십시오.

signal()은 표준 C이지만 sigaction()은 표준 C가 아닙니다.

어느쪽인가를 사용할 수 있는 경우는(즉, POSIX 시스템상에 있는 경우), sigaction()을 사용합니다.signal()이 핸들러를 리셋 할지는 지정되지 않았습니다.즉, 포터블을 하려면 핸들러 내부에서 signal()을 다시 호출해야 합니다.더 나쁜 것은 경합이 있다는 것입니다.빠른 속도로 2개의 신호가 연속적으로 수신되고 핸들러를 재설치하기 전에 두 번째 신호가 전달되면 기본 액션이 실행되므로 프로세스가 중단될 수 있습니다.한편, sigaction은, 「신호 의미론」을 사용하는 것을 보증합니다.핸들러는 리셋 되지 않기 때문에, 재인스톨 할 필요는 없습니다.SA_RESTART를 사용하면 시스템 콜을 자동으로 재시작할 수도 있습니다(수동으로 EINTR을 확인할 필요가 없습니다).sigaction()은 옵션이 많고 신뢰성이 높기 때문에 사용을 권장합니다.

Psst... 아무에게도 말하지 마세요.그러나 POSIX는 현재 signal()과 같이 동작하지만 BSD의 의미를 부여하는 bsd_signal() 함수를 가지고 있습니다.이것은 신뢰성이 있다는 것을 의미합니다.주로 신뢰성 높은 신호를 가정한 오래된 애플리케이션을 이식하는 데 사용되며 POSIX에서는 사용을 권장하지 않습니다.

man 페이지부터:

묘사

 This signal() facility is a simplified interface to the more
 general sigaction(2) facility.

둘 다 동일한 기본 기능을 호출합니다.아마도 하나의 신호로 양쪽 신호를 조작해서는 안 될 것입니다만, 그것들을 혼합하는 것으로 인해, 아무것도 망가져서는 안 됩니다.

signal()보다 sigaction()을 사용하는 것도 추천합니다.또한 sigaction()은 정지된 프로세스의 pid 등의 옵션을 제공합니다(siginfo_t 구조를 사용할 수 있습니다).

적어도 이론상으로는 signal()이 더 휴대성이 좋기 때문에 사용합니다.POSIX 호환 레이어가 없고 signal()을 지원하는 최신 시스템을 생각해 낼 수 있는 코멘터라면 누구에게나 투표하겠습니다.

GLIBC 문서에서 인용한 내용:

하나의 프로그램 내에서 신호와 시그니션 기능을 모두 사용할 수 있지만, 조금 이상한 방식으로 상호작용할 수 있기 때문에 주의해야 합니다.

sigaction 함수는 신호 함수보다 더 많은 정보를 지정하기 때문에 신호로부터의 반환 값은 시그니션의 모든 가능성을 표현할 수 없습니다.따라서 신호를 사용하여 액션을 저장하고 나중에 재정립할 경우 시그니션으로 확립된 핸들러를 올바르게 재정립하지 못할 수 있습니다.

결과적으로 문제가 발생하는 것을 방지하기 위해 프로그램에서 시그액션을 사용하는 경우 항상 시그액션을 사용하여 핸들러를 저장하고 복원합니다.시그널 액션은 일반적인 것이므로 원래 시그널 또는 시그널 액션이 확립되어 있던지 여부에 관계없이 모든 액션을 적절히 저장하고 재정립할 수 있습니다.

일부 시스템에서는 신호로 액션을 확립한 후 시그널로 검사하면 취득한 핸들러 주소가 신호로 지정한 주소와 다를 수 있습니다.신호와 함께 동작 인수로 사용하기에 적합하지 않을 수도 있습니다.하지만 당신은 그것을 시그액션의 논거로 사용할 수 있습니다.이 문제는 GNU 시스템에서는 발생하지 않습니다.

따라서 하나의 프로그램 내에서 일관되게 어느 하나의 메커니즘을 사용하는 것이 좋습니다.

휴대성에 관한 주의:기본 신호 기능은 ISO C의 기능이며 시그니션은 POSIX.1 표준의 일부입니다.비 POSIX 시스템에 대한 이식성이 우려되는 경우 대신 신호 기능을 사용해야 합니다.

Copyright (C) 1996-2008 Free Software Foundation, Inc.

이 문서의 복사, 배포 및/또는 수정은 자유 소프트웨어 재단이 발행한 GNU Free Documentation License, 버전 1.2 또는 이후 버전에 따라 허가됩니다.불변 섹션, 전면 커버 텍스트 및 후면 커버 텍스트가 없습니다.라이센스 사본은 "GNU Free Documentation License" 섹션에 포함되어 있습니다.

송신원 페이지 신호(7)

프로세스 지향 신호는 현재 신호가 차단되지 않은 스레드 중 하나에 전달될 수 있습니다.둘 이상의 스레드에 신호가 차단되지 않은 경우 커널은 신호를 전달할 임의의 스레드를 선택합니다.

그리고 이 '문제'는 신호(2)와 신호(2)에 존재한다고 말할 수 있습니다.그러니까 신호와 pthread를 조심하세요.

glibc를 사용하는 Linux에서는 signal(2)이 아래에 있는 sigaction(2)을 호출하는 것 같습니다.

언급URL : https://stackoverflow.com/questions/231912/what-is-the-difference-between-sigaction-and-signal

반응형