programing

MSYS 'bash'로 인해 ^C를 트랩하는 프로세스가 파괴되지 않도록 방지

closeapi 2023. 9. 23. 22:44
반응형

MSYS 'bash'로 인해 ^C를 트랩하는 프로세스가 파괴되지 않도록 방지

콘솔 모드 Windows 응용 프로그램(유닉스에서 포팅)이 있습니다. 원래는 수신할 때 깨끗하게 종료되도록 설계되었습니다(유닉스).SIGINT이 경우에는 원격 네트워크 연결이 종료될 때까지 상당한 시간이 걸릴 수 있습니다. (정상적인 동작이 아니라는 것은 알지만 변경할 수 있는 위치에 있지 않습니다.)프로그램이 싱글 스레드입니다.

나는 둘 중 하나로 덫을 놓을 수 있습니다.signal(SIGINT)(유닉스 아래에서와 같이) 또는 . CMD 아래에서 프로그램이 실행될 때 둘 중 하나가 올바르게 작동합니다.EXE. 그러나 MSYS와 함께 제공되는 "bash" 셸을 사용하면(유닉스 makefiles를 재사용할 수 있으므로 MinGW 환경을 사용하여 프로그램을 빌드하고 있습니다) 프로그램이 강제로 종료됩니다(100밀리초 미만).이는 허용할 수 없습니다. 앞서 언급한 바와 같이 프로그램은 원격 네트워크 연결이 종료될 때까지 기다려야 하기 때문입니다.

사람들은 MSYS bash 아래에서 이 프로그램을 실행하기를 원할 가능성이 높습니다.또한 이 효과로 인해 테스트 제품군이 손상됩니다.프로그램 내에서(이상적인) 또는 셸의 설정(수용 가능한)을 통해 문제를 해결할 수 있는 방법을 찾을 수 없었습니다.추천해 주실 분?

저는 SIGINT/SIGTERM 핸들러로 프로그램을 작성한 적이 있습니다.그 핸들러는 청소 작업을 했는데, 가끔 시간이 좀 걸렸습니다.msys bash 내에서 프로그램을 실행하면 ctrl-c로 인해 SIGINT 핸들러가 발생하지만 완료되지 않습니다. 프로그램이 정리 작업을 완료하기 전에 프로그램이 종료되었습니다.

박사들의 답변을 바탕으로 https://stackoverflow.com/a/23678996/2494650, 저는 다음과 같은 해결책을 생각해 냈습니다.너무 간단해서 아직 발견하지 못한 부작용이 있을 수도 있지만, 문제를 해결해 주었습니다.

다음 행으로 ~/.bashrc 파일을 만듭니다.

trap '' SIGINT

바로 그겁니다.이렇게 하면 signint 신호가 트랩되고 msys bash가 "외부에서" 프로그램을 종료하지 못하게 됩니다.그러나 SIGINT가 프로그램에 신호를 전달하여 원활한 정리/종료를 할 수 있게 해줍니다.왜 이런 식으로 작동하는지 정확하게 말씀드릴 수는 없지만, 적어도 저한테는 그렇습니다.

행운을 빕니다.

이것은 악명 높은 민트색 "외계 프로그램과의 입출력 상호작용" 문제 때문일 수 있습니다(일명 민트색 문제 #56).이 경우, Ctrl-C가 프로그램을 잡고 처리해야 할 신호로 전달되지 않고 프로그램을 갑자기 죽이는 것으로 나타납니다.이 이론에 대한 증거는 zwol의 광범위한 설명에 기반을 두고 있습니다: "콘솔 모드 윈도우 응용 프로그램", "[응용 프로그램은] 수신했을 때 깨끗한 종료를 하도록 설계되었습니다", "[응용 프로그램은] CMD에서 프로그램이 실행될 때 올바르게 작동합니다.EXE" 그러나 "MSYS [...] 프로그램과 함께 제공되는 단말기 사용 시 강제 종료" (작성 당시 (2018년) MSYS는 기본적으로 민티를 단말기로 사용합니다.

안타깝게도 minty는 Windows 콘솔을 완전히 대체하는 것은 아니며 "원어민" Windows 프로그램에서 예상되는 다양한 동작은 구현되지 않습니다.하지만 그런 프로그램들을 아주 짧은 시간 안에 실행할 때 그런 토종 프로그램들을 윈티하게 포장하는 것이 즐거울지도 모릅니다.

다른 질문에서도 이 동작에 대해 설명합니다. https://superuser.com/questions/606201/how-to-politely-kill-windows-process-from-cygwin 및 https://superuser.com/questions/1039098/how-to-make-mintty-close-gracefully-on-ctrl-c 을 참조하십시오.

Arg - 댓글에 5분 편집.다음은 제가 쓰고 싶었던 것입니다.

해결 방법으로 셸로 전파되는 CTRL-C 이벤트를 트랩하려고 하는 대신 ENABLED_PROCED_를 끄는 것을 제안합니다.CTRL-C가 신호 대신 키보드 입력으로 보고되도록 stdin에서 입력:

DWORD mode;
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hstdin, &mode);
SetConsoleMode(hstdin, mode & ~ENABLE_PROCESSED_INPUT); /* disable CTRL-C processing as a signal */

그러면 다른 프로그램이 별도의 스레드에서 작업하는 동안 메인 스레드에서 키보드 입력을 처리하고 CTRL-C가 수신될 때 이벤트를 정리하도록 설정할 수 있습니다.

MSYS bash로 프로그램을 실행할 때 실행 파일을 직접 실행합니까, 아니면 래핑(bash) 셸 스크립트가 있습니까?

Ctrl-C 지정 일 수 trap명령(잠을 자고 나서 킬을 수행합니다.)그런 것이 있으면 그것을 바꾸거나 제거합니다.

trap등록되었거나 래핑 스크립트가 없는 경우에는 이러한 스크립트를 만들고 기본 동작을 재정의하기 위해 자신의 트랩을 추가하는 것을 고려해 보십시오.여기 또는 bash의 man page(SHELL BUILTINS 섹션)에서 사용 방법의 예를 볼 수 있습니다.

Ctrl-C가 SIGINT?저는 Ctrl-Z가 SIGINT인 줄 알았는데 Ctrl-C가 SIGTEM입니다.확인해보세요.

CYGWIN 환경 설정(제어판/환경 변수)이 있습니까?CYGWIN=notty를 설정하고 새 MSYS 배시 셸을 다시 시작해 보십시오. 문제가 지속됩니까?

언급URL : https://stackoverflow.com/questions/7085492/preventing-msys-bash-from-killing-processes-that-trap-c

반응형