dup & dup2

오젼·2022년 11월 19일
1

dup vs dup2

  • dup이 복사 개념 dup2가 덮어쓰기 개념이라고 생각하면 될 것 같다.
  • pipe를 할 때 dup2로 STDIN 또는 STDOUT을 pipe()로 할당한 fd에 연결하는 것은
  • command들이 원래 표준입출력의 fd인 0 또는 1을 통해 읽거나 쓰게 되어 있기 때문에 dup2로 0과 1이 가리키는 곳을 바꿔줬던 것.
  • 대신 dup2를 하면 기존에 가리키고 있던 곳을 잃어 버리기 때문에, dup 으로 원래 가리키던 STDIN, STDOUT을 가리킬 또다른 fd값을 남겨뒀던 것.

pipe & fork

  • fd[2]를 선언 후 pipe(fd); 하게 되면 pipe 사용할 fd가 할당 됨.
  • pipe fd 만들어둔 다음 fork()를 하게 되면, 자식 프로세스에 pipe fd가 그대로 복사 됨. fork 하기 전까지의 작업 상태가 그대로 복사된 child가 만들어 지는 것.
  • fork 이후의 변화는 서로 독립적임

  • 위에서처럼 파이프 2개 썼다고 할 때
  • 사전작업: STDIN과 STDOUT이 가리키던 곳을 dup으로 백업해둬야 한다. (dup2로 fd 0과 1이 가리키는 곳을 바꾸면 기존에 STDIN과 STDOUT을 가리키던 곳을 잃어버리기 때문에)
    sd[0] = dup(0); sd[1] = dup(1);
  1. 첫 번째 프로세스의 자식은 STDIN에서 읽어오고 fd[1]에 씀.
    이제 이 fd를 다음 프로세스에서 사용해야 하기 때문에 backup 해줄 것임.
    bd[0] = fd[0]; bd[1] = fd[1];
  2. 두 번째 프로세스에서 pipe로 fd를 새로 할당.
    두 번째 프로세스의 자식은 bd[0]에서 읽고 fd[1]에 씀.
    자식 프로세스가 끝날 때까지 기다리던 부모 프로세스에서 bd를 모두 닫음. close(bd[0]); close(bd[1]);
    다시 이번에 사용했던 fd를 백업.
    bd[0] = fd[0]; bd[1] = fd[1];
  3. 세 번째 프로세스에서 pipe로 fd를 새로 할당.
    세 번째 프로세스의 자식은 bd[0]에서 읽고 STDOUT에 씀.
    자식 프로세스가 끝날 때까지 기다리던 부모 프로세스에서 bd를 모두 닫음.
    close(bd[0]); close(bd[1]);
  • bd를 close하는 것은 descriptor의 낭비도 줄일 수 있으며
    (이미 사용이 끝난 fd를 close하지 않고 놔두면, 다른 fd를 할당할 때 fd값을 계속해서 늘려서 할당해 줘야 함.
    ex- 3,4를 안 쓰는데 close를 안 해두면 다음에 pipe(fd)를 할 때 5,6이 할당 되지만, 3,4를 close하고 나서 pipe(fd)를 하면 3,4가 할당 된다.)
  • 입출력이 끝난 파이프를 broken pipe로 만들어 이미 깨진 파이프에 접근하는 프로세스가 있을 때 SIGPIPE를 날려 처리할 수 있는 역할도 한다.

0개의 댓글