파이프 버퍼

오젼·2023년 1월 5일
0

문제

한 줄 요약

  • pipe에 write를 하려고 할 때 write할 문자열이 크면 partial write가 발생하는데 파이프 버퍼사이즈(65536byte) 만큼 두 번 쓰고 나면 kevent에서 block 되었음.

원인

  • 원래는 파이프에 쓴 거를 바로 읽으면 파이프가 가득찰 일이 없음. 그런데
  • child가 1번 파이프에서 읽고 부모에게 2번 파이프로 결과를 쓰는데
  • 결과를 모두 쓸 때까지(결과의 길이만큼 write를 하기 전까지) kevent에 READ_EVENT를 등록하지 않았음.
  • 파이프 버퍼 크기보다 결과의 길이가 컸던 경우, partial write가 발생하게 됐고
  • 2번 파이프의 버퍼가 가득 찬 상태에서
  • 또 write를 할 수 없어 blocking 상태에 빠지게 된 것.

해결

  • 원래는 무조건
  1. WRITE_EVENT를 등록해서 부모 프로세스가 1번 파이프로 write 하게 하고
  2. READ_EVENT를 등록해서 자식 프로세스가 1번 파이프에서 read 하고
  3. WRITE_EVENT를 등록해서 execve한 결과를 2번 파이프에 write 하면
  4. READ_EVNET를 등록해서 부모 프로세스가 2번 파이프에서 read 하게 했는데
  • 애초에 두 이벤트를 kqueue에 동시에 등록하고 READ_EVENT가 발생했을 땐 read pipe를 하고 WRITE_EVENT가 발생했을 땐 write pipe를 하고..
  • 이렇게 동시에 처리할 수 있도록 해줘야 하는 거였음.

0개의 댓글