close — 열린 채널 닫기

close — 열린 채널 닫기

파일이나 소켓에서 입출력이 끝나면 채널을 닫아 자원을 정리해야 해요. close는 그 역할을 하는 명령으로, 완전히 닫거나(half-close) 한쪽 방향만 닫는 것도 지원합니다.

출처: close manual page

본문

close channelId ?r(ead)|w(rite)?

channelId로 주어진 채널을 닫거나 반쪽만 닫습니다. channelId는 Tcl 표준 채널(stdin, stdout, stderr), open이나 socket 호출의 리턴값, 또는 Tcl 확장이 제공하는 채널 생성 명령의 결과 같은 열려 있는 채널의 식별자여야 합니다.

인자 하나짜리 형태는 간단한 "완전 닫기"예요. 버퍼링된 모든 출력은 채널의 출력 장치로 flush되고, 버퍼링된 입력은 버려지며, 밑의 파일이나 장치가 닫히고 channelId는 더 이상 사용할 수 없게 됩니다.

채널이 블로킹 모드면 명령은 모든 출력이 flush될 때까지 리턴하지 않아요. 채널이 논블로킹이고 flush되지 않은 출력이 있으면 채널은 열린 채로 명령이 즉시 리턴합니다. 출력은 백그라운드에서 flush되고, 모든 flushing이 끝나면 채널이 닫혀요.

channelId가 명령 파이프라인의 블로킹 채널이면 close는 자식 프로세스들이 끝나기를 기다립니다.

채널이 인터프리터들 사이에서 공유되면, close는 호출한 인터프리터에서 channelId를 사용할 수 없게 만들 뿐이고, 채널을 공유하는 인터프리터들이 전부 닫을 때까지는 다른 효과가 없어요. 채널이 등록된 마지막 인터프리터가 close를 호출하면 위에서 설명한 정리 작업이 일어납니다. 채널 공유에 대한 설명은 interp 명령을 참조하세요.

채널은 인터프리터가 파괴될 때와 프로세스가 종료될 때 자동으로 닫힙니다. 8.6부터(TIP#398) 논블로킹 채널은 종료 시 더 이상 블로킹 모드로 전환되지 않습니다. 이로 인해 피어나 통신 채널이 멈춰 있어도 제때 종료되는 것을 보장해요. 종료 시 멈춘 논블로킹 채널을 제대로 flush하려면 (a) 능동적으로 다시 블로킹으로 전환하거나 (b) 환경 변수 TCL_FLUSH_NONBLOCKING_ON_EXIT를 사용해야 하는데, 이 변수를 설정하고 "0"이 아니면 예전 동작을 복원합니다.

이 명령은 빈 문자열을 리턴하며, 출력을 flush하는 동안 오류가 발생하면 오류를 낼 수 있어요. open으로 만든 명령 파이프라인의 명령이 오류를 리턴하면 close가 오류를 발생시킵니다(exec 명령과 비슷합니다).

두 인자짜리 형태는 "반쪽 닫기(half-close)"예요. 소켓이나 명령 파이프라인 같은 양방향 채널과 (축약 허용) 방향이 주어지면 그 방향으로 가는 하위 스트림만 닫습니다. 소켓에서는 shutdown()을, 명령 파이프라인에서는 파이프의 한쪽 끝의 close()를 의미해요. 그런 다음 Tcl 레벨 채널 데이터 구조는 다른 방향이 여전히 열려 있는지에 따라 유지되거나 해제됩니다.

이미 반쪽 닫힌 양방향 채널에 대한 인자 하나짜리 close는 그냥 "일을 마무리"하는 것으로 정의됩니다. 이미 닫힌 절반이나 잘못된 방향의 단방향 채널에 반쪽 닫기를 하면 오류가 발생해요.

명령 파이프라인의 경우, 자식 프로세스를 회수하는 의무는 마지막 close나 half-close가 지며, 따라서 비정상 종료 오류를 보고할 수 있습니다.

현재 반쪽 닫기를 지원하는 것은 소켓과 명령 파이프라인뿐입니다. 향후 확장으로 reflected 채널과 stacked 채널도 지원할 예정입니다.

예시

다음은 catch, close, return을 조합해 오류가 발생해도 파일이 닫히도록 보장하는 방법을 보여줍니다:

proc withOpenFile {filename channelVar script} {
    upvar 1 $channelVar chan
    set chan [open $filename]
    catch {
        uplevel 1 $script
    } result options
    close $chan
    return -options $options $result
}

더 알아보기

  • file, open, socket, eof, Tcl_StandardChannels — 채널과 파일 입출력
  • 키워드: blocking, channel, close, nonblocking, half-close