2014-11-01 3 views
1

세 스트림의 동작을 이해하려고합니다. stdout, stdinstderr입니다. 어떤 교과서에서 답을 얻을 수 없었으므로 여기에 왔습니다.stdin, stdout 및 stderr는?

이 세 가지는 파일 설명자 0 (stdin), 1 (stdout) 및 2 (stderr)로 파일 설명자 테이블에 저장된다는 것을 알고 있습니다. 나는 또한 이것이 단지 파일 기술자가 아니라 방향 전환 될 수있는 I/O 스트림이라는 것을 알고있다. 좋아, 공유는 어때? 표준 오류 자식 프로세스와 부모 프로세스를 공유 파일 설명을하지만, 그들은 같은 표준 입력, 표준 출력을 가지고 않습니다 포크()가를 호출하면

  1. :

    는 세 가지 사례를 고려?

  2. 스레드가 생성 될 때 : 스레드는 파일 설명자를 공유하지만 입출력 스트림은 없습니까?
  3. execl()이 호출 될 때 :이 경우 현재 프로세스 이미지는 새 프로세스 이미지로 겹쳐 쓰여집니다. execl("./a.out", "a.out", NULL);을 수행하면이 새로운 실행 파일에 stdin, stderr 및 stdout의 새로 고침이 생깁니 까?

모든 답변을 환영합니다.

답변

2

무슨 일이 일어나고 있는지 이해하려면 프로세스 경계를 ​​넘나 드는 커뮤니케이션 채널이라고 생각하십시오. 나는 그것들을 다른 컨텍스트에서 사용되기 때문에 스트림이라고 부르지 않을 것이다. 그러나 그것들은 관련되어있다.

먼저, filedescriptor는 이러한 채널을 나타내는 프로세스 별 테이블에 대한 인덱스이며, 기본적으로 불투명 한 핸들입니다. 그러나 스레드가 프로세스의 일부이기 때문에이 디스크립터도 공유하므로 두 스레드에서 동일한 채널로 쓰면 동일한 채널을 통해 빠져 나오므로 프로세스 외부에서 두 스레드 구별 할 수 없다.

그런 다음 fork()가 호출되면 프로세스가 효과적으로 복사됩니다. 이것은 copy-on-write 최적화로 수행되지만, 여전히 이들 통신 채널을 나타내는 다른 테이블을 가지고 있음을 의미합니다. 하나의 프로세스에서 인덱스 2가있는 항목은 포크에서 인덱스 2가있는 항목과 동일하지 않습니다. 이는 프로세스 내부에있는 모든 구조에 대해 동일합니다. C FILE* 또는 C++ std::stream을 맨 위에 작성한 경우 다른 데이터와 함께 복사됩니다.

execl()이 호출되면 프로세스는 여전히 특정 채널을 외부에 "소유"합니다. 이것들은 프로세스를 관리하는 OS로부터 할당된다. 이것은 인덱스 2가 외부 세계와 통신하는 데 여전히 사용될 수 있음을 의미합니다. 시작시, 런타임 라이브러리는 예를 들어 다음을 생성합니다. 3 개의 잘 알려진 채널 stdin, stdout 및 stderr에 대해 C에서 사용하기위한 FILE *.

남아있는 질문은 프로세스가 외부의 채널로 분기 될 때 발생합니다.여기에 대한 대답은 간단합니다. 채널이 닫혀 있거나 상속되었거나 채널 기반으로 구성 될 수 있습니다. 상속 된 경우 하위 프로세스에서 계속 사용할 수 있습니다. 상속 된 채널에 쓰여진 내용은 상위 프로세스의 출력이 끝날 때까지 끝납니다.

분기 된 프로세스의 stdin에 대해서는 실제로 확신 할 수 없습니다. 입력을 여러 대상에 보내는 것이 의미가 없기 때문에 입력이 기본적으로 닫힌 것 중 하나라고 생각합니다. 또한 부모 프로세스가 제공 한 입력을 제외하고는 자식 프로세스에서 stdin의 입력을 실제로 처리해야 할 필요성을 느끼지 못했습니다 (부모와 자식이 아닌 형제이지만 셸의 파이프와 비슷 함).

참고 : 명확한 설명이없는 경우 궁금한 점이 있으시면 언제든지 문의 해 주시기 바랍니다. 이해를 돕기 위해 노력하겠습니다.

+0

elabroted 답장을 보내 주셔서 감사합니다. 나는 그것을 받아들이는 것이 약간 힘들다는 것을 알았다. 내가 이해하는 바와 같이, 2와 3의 경우, stdin, stdout 및 stderr는 공유된다. 나는 fork() 케이스에 대해 이해할 수 없다. 파일이 부모 프로세스에 의해 열리고 자식 프로세스에 의해 다시 열리는 경우를 말합니다. 두 파일 기술자는 독립적입니까? – 0aslam0

+0

또한 여기에서 확인하십시오. http://stackoverflow.com/questions/26696811/making-stdin-writable-in-a-safe-and-portable-way – 0aslam0

+0

예, 2와 3 표준 스트림을 공유하는 경우 스레드는 항상 프로세스와 execl을 공유합니다.()는 프로세스를 변경하지 않습니다 (프로세스가 수행하는 것만 변경합니다). fork()의 ​​경우, 상속 된 스트림은 자식 프로세스에서 계속 사용할 수 있습니다. 이 경우, 데이터는 부모 프로세스와 자식 프로세스 모두에서 데이터를 수신하는 프로세스로 전달됩니다. –

0

역전으로 가정합니다.

만약 그들이 같은 위치를 공유하지 않았다면 (즉, 파일 디스크립터가 무엇인지),이 시나리오는 뭔가를 불러 일으킬 것입니까? 그것은 가능합니다 - 결정 론적 기계에서 결론 지을 수 있습니다.

답변이 있습니다. 네, 그들은 같은 위치를 공유합니다.

+0

좋습니다. 그것은 나의 결론이기도하다. 그러나 그것을 점검하기 위해 작은 코드를 실행하려고 할 때 예기치 않은 오류가 발생했습니다. 질문을 추가하거나 새 질문을 게시해야합니까? – 0aslam0

+0

@ xachu4u - 그건 당신의 선택입니다 –

관련 문제