문제

Win32 CreateFile 가지다 FILE_FLAG_DELETE_ON_CLOSE,하지만 저는 리눅스에 있습니다.

프로그램 종료시 항상 삭제되는 임시 파일을 열고 싶습니다. 프로그램 충돌의 경우이를 보장하는 것이 실용적이지 않을 수 있지만 다른 경우에는 작동하고 싶습니다.

나는 Raii에 대해 알고 있습니다. 신호에 대해 알고 있습니다. 나는 알고있다 atexit(3). 파일을 열고 즉시 삭제할 수 있고 파일 디스크립터가 닫힐 때까지 파일에 액세스 할 수 있습니다 (충돌도 처리). 이들 중 어느 것도 완전하고 간단한 솔루션처럼 보이지 않습니다.

  1. Raii : 그곳에 있었다. 그랬다 : 나는 파일을 삭제하는 객체가 있지만 프로그램이 신호에 의해 종료되면 소멸자가 호출되지 않는다.
  2. 신호 : 저는 신호 핸들러를 까다로운 제안으로 만드는 저수준 라이브러리를 쓰고 있습니다. 예를 들어, 응용 프로그램이 신호 자체를 사용하면 어떻게됩니까? 나는 발가락을 밟고 싶지 않습니다. 나는 영리한 사용을 고려할 수 있습니다 sigaction(2) 대처하기 위해 ... 그러나 아직이 가능성에 대해 충분한 생각을하지 않았습니다.
  3. atexit(3): 비정상 종결 중에 호출되지 않기 때문에 (예 : 신호를 통한) 분명히 쓸모가 없습니다.
  4. 선제 적 unlink(2): 파일 시스템에서 파일이 표시되도록 파일이 필요하다는 점을 제외하고는 꽤 좋습니다 (그렇지 않으면 시스템이 모니터링/문제 해결하기가 더 어렵습니다).

여기서 무엇을 하시겠습니까?

추가 설명

나는 원래 게시물에서 하나의 세부 사항을 포함 시켰습니다. 이 경우 "파일"은 엄격하게 일반 파일이 아니라 POSIX 메시지 대기열입니다. 나는 그것을 통해 그것을 만듭니다 mq_open(). 닫을 수 있습니다 mq_close() 또는 close() (전자는 내 시스템의 후자의 별칭입니다). 시스템에서 제거 할 수 있습니다 mq_unlink(). 이 모든 것이 일반 파일과 유사하게 만듭니다. 제외하고 파일에 상주하는 디렉토리를 선택할 수 없습니다. 이것은 현재 가장 인기있는 답변을 만듭니다 (파일을 /tmp) "파일"은 용량이 매우 제한된 가상 파일 시스템에서 시스템에 의해 생성되기 때문에 불가능합니다. (가상 파일 시스템을 장착했습니다 /dev/mqueue, 예제에 따라 man mq_overview) .

또한 이름이 눈에 띄게 유지되는 이유를 설명합니다 (즉각적인 링크 접근 방식을 실행할 수 없음) : "파일"은 둘 이상의 프로세스간에 공유해야합니다.

도움이 되었습니까?

해결책

프로세스가 실행되는 동안 이름이 표시되어야한다는 요구 사항으로 인해이를 달성하기가 어렵습니다. 해당 요구 사항을 다시 방문 할 수 있습니까?

그렇지 않다면 완벽한 솔루션이 없을 것입니다. 신호 처리 전략을 Kamil Kisiel의 제안과 결합하는 것을 고려할 것입니다. 신호 처리기를 설치하기 전에 설치된 신호 처리기를 추적 할 수 있습니다. 기본 핸들러가 sig_ign 인 경우 일반적으로 자신의 핸들러를 설치하지 않습니다. 그것이 sig_dfl이라면, 당신은 그것을 기억할 것입니다; 사용자 정의 신호 핸들러 인 다른 것이라면 해당 포인터를 기억하고 직접 설치할 수 있습니다. 핸들러가 호출되면해야 할 일을 수행 한 다음 기억 된 처리기를 호출하여 처리기를 체인 할 수 있습니다. 또한 atexit () 핸들러를 설치합니다. 당신은 또한 당신이 이것을하는 것을 문서화하고 당신이하는 신호를 문서화 할 것입니다.

신호 처리는 불완전한 전략입니다. Sigkill을 잡을 수 없으며 AtexIt () 핸들러가 호출되지 않으며 파일이 남아 있습니다.

David Segond의 제안 (임시 파일 이름 데몬)은 흥미 롭습니다. 간단한 프로세스의 경우 충분합니다. 임시 파일을 요청하는 프로세스가 포크하고 그 이후에 파일을 소유 할 것으로 예상하는 경우 (및 종료) 데몬은 IT를 사용하는 마지막 프로세스가 죽을 때 감지하는 데 문제가 있습니다.

다른 팁

임시 파일 만 만들고 있다면 /tmp 또는 그 하위 디렉토리. 그런 다음 끝날 때 최선을 다해 제거하십시오. atexit(3) 또는 유사합니다. 고유 한 이름을 사용하는 한 mkstemp(3) 또는 프로그램 충돌로 인해 삭제되지 않더라도 이와 유사하면 후속 실행이나 다른 조건에서 다시 읽을 위험이 없습니다.

그 시점에서 그것은 단지 시스템 수준의 문제 일뿐입니다. /tmp 깨끗한. 대부분의 배포판은 부팅 또는 종료시를 닦거나 일반 크론 조브를 실행하여 이전 파일을 삭제합니다.

어쩌면 누군가가 이미 이것을 제안했지만, 당신의 모든 요구 사항을 감안할 때, 내가 생각할 수있는 가장 좋은 것은 파일 이름을 어떻게 든 시작 스크립트와 같은 학부모 프로세스에 전달하는 것입니다. 프로세스가 사라지고 그렇게하지 못했습니다. 이것은 아마도 대부분 감시자로 알려져 있지만, 더 일반적인 사용 사례가 추가되어 어떻게 든 실패 할 때 프로세스를 킬 및/또는 다시 시작합니다.

부모의 프로세스도 사망하면 운이 좋지 않지만 대부분의 스크립트 환경은 대본이 깨지지 않으면 상당히 강력하고 거의 죽지 않으며, 이는 종종 프로그램보다 정확하게 유지하기가 더 쉽습니다.

과거에는 임시 파일을 추적하는 "임시 파일 관리자"를 빌드했습니다.

하나는 관리자에게 임시 파일 이름을 요청 하고이 이름은 등록되었습니다.

더 이상 임시 파일 이름이 필요하지 않으면 관리자에게 알리고 파일 이름에 등록되지 않습니다.

종료 신호를 받으면 등록 된 모든 임시 파일이 파괴되었습니다.

임시 파일 이름은 충돌을 피하기 위해 UUID를 기반으로했습니다.

파일을 만든 후 프로세스가 포크를 가질 수 있으며, 아이가 닫기를 기다린 다음 부모가 파일을 풀고 종료 할 수 있습니다.

방금 stackoverflow에 가입하고 여기서 당신을 찾았습니다 :)

문제가 MQ 파일을 관리하고 쌓는 것을 막는 것이 문제가되는 경우, 종료시 파일 삭제를 보장 할 필요는 없습니다. 쌓아 올리는 것을 쓸모없는 파일을 원한다면 저널을 유지하는 것보다 필요한 전부 일 수 있습니다. MQ가 열린 후 저널 파일에 항목을 추가하고, 다른 항목이 닫히고, 라이브러리가 초기화되면, 저널의 불일치를 확인하고 불일치를 수정하는 데 필요한 조치를 취하십시오. 때때로 충돌에 대해 걱정하는 경우 mq_open/mq_close 호출되면 해당 기능이 호출되기 직전에 저널 항목을 추가 할 수도 있습니다.

  • 도트 디렉토리 아래에 임시 파일에 대한 부기 키핑 디렉토리가 있습니다.
  • 온도 파일을 만들 때 먼저 To To To Temp 파일에 경로 또는 UUID가 포함 된 부기 디렉토리에 부기 파일을 작성하십시오.
  • 그 임시 파일을 만듭니다.
  • Temp-File이 삭제되면 부기 파일을 삭제하십시오.
  • 프로그램이 시작되면 임시 파일의 경로가 포함 된 파일에 대한 부기 키핑 디렉토리를 스캔하고 찾은 경우 삭제하려고하면 부기 파일을 삭제하십시오.
  • (어떤 단계가 실패하면 시끄럽게 로그를 작성하십시오.)

나는 그것을 더 간단하게하는 방법을 보지 못합니다. 이것은 모든 생산 품질 프로그램이 겪어야하는 보일러 플레이트입니다. 쉽게 +500 라인.

당신은 ~ 진짜 눈에 보이려면 이름이 필요하십니까?

파일을 즉시 인쇄하지 않는 옵션을 받고 있다고 가정 해 봅시다. 그 다음에:

  • 선점 무제액 (2) : 파일 시스템에서 파일이 표시되도록 파일이 필요하다는 점을 제외하고는 꽤 좋습니다 (그렇지 않으면 시스템이 모니터링/문제 해결하기가 더 어렵습니다).

    여전히 삭제 된 파일에서 디버깅 할 수 있습니다. /proc/$pid/fd/. 프로세스의 PID를 아는 한 열린 파일을 열거하는 것이 쉬울 것입니다.

  • 이름은 프로그램간에 공유되기 때문에 정상 작동 중에 눈에 띄게 유지되어야합니다.

    Unix 도메인 소켓을 통해 파일 디스크립터를 전달하여 프로세스간에 삭제 된 열린 파일을 여전히 공유 할 수 있습니다. 보다 다른 프로세스간에 파일 디스크립터를 전달하는 휴대용 방법 자세한 내용은.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top