Quiz: what unguaranteed ordering causes
한국어 원문으로 표시합니다.
여덟 프로세스가 같은 순간에 카운터를 하나씩 올렸는데 최종 값이 1 이었다. 무슨 일이 일어난 것인가?
- 파일 시스템이 동시 쓰기를 거부해 일곱 프로세스의 쓰기가 오류로 끝났다
- 여덟이 모두 0 을 읽은 뒤 각자 1 을 썼기 때문에, 나중에 쓴 값이 앞의 결과를 덮었다
- 커널이 같은 파일에 대한 쓰기를 직렬화하면서 마지막 하나만 반영했다
- 프로세스가 여덟 개여도 코어가 둘이면 실제로는 두 개만 동시에 실행되어 값이 줄었다
open(path, "w") 로 연 뒤 fcntl.flock 으로 배타 잠금을 걸었다. 무엇이 잘못됐는가?
- flock 은 쓰기 모드로 연 파일에는 걸리지 않으므로 잠금이 조용히 무시된다
- 잠금을 건 뒤에 쓰기 모드로 다시 열어야 하므로 파일 기술자가 두 개 필요하다
- "w" 는 여는 순간 파일을 비우므로, 잠금을 얻기 전에 이미 남의 자료가 사라진다
- flock 은 경로가 아니라 파일 기술자에 걸리므로 다른 프로세스에는 보이지 않는다
"리스 파일이 없으면 만든다" 를 os.path.exists 로 확인한 뒤 open 으로 만들었다. 가장 정확한 설명은?
- 확인과 생성 사이에 틈이 있어 여러 프로세스가 모두 자기가 주인이라고 믿을 수 있다
- os.path.exists 가 캐시된 결과를 돌려주므로 방금 만들어진 파일을 못 볼 수 있다
- open 이 파일을 만들 때 잠금을 걸지 않으므로 나중에 쓰는 쪽이 이긴다
- 두 호출이 서로 다른 시스템 호출이므로 파일 기술자가 새어 결국 한도에 걸린다
설정 파일을 통째로 다시 쓰는 동안 읽는 쪽에서 JSON 파싱 오류가 난다. 가장 적절한 해법은?
- 읽는 쪽에 재시도를 넣어 파싱 오류가 나면 잠시 뒤 다시 읽게 한다
- 쓰는 쪽에서 파일을 한 번에 write 하고 flush 와 fsync 로 디스크까지 내려 쓴다
- 읽는 쪽이 파일 크기를 먼저 확인해 0 이 아닐 때만 읽도록 한다
- 같은 디렉터리의 임시 파일에 전부 쓴 뒤 os.replace 로 이름을 바꿔 끼운다
경쟁 조건을 재현하려고 출발 표식 파일을 쓰는 하네스를 만들었다. 이 방식의 값어치는?
- 프로세스 수를 늘리지 않고도 부하를 키워 실제 운영과 같은 조건을 만들 수 있다
- 가끔 일어나던 일을 언제나 일어나게 만들어, 고쳤다는 것도 같은 방법으로 증명할 수 있다
- 커널의 스케줄러를 고정해 프로세스가 실행되는 순서 자체를 정해 줄 수 있다
- 잠금 없이도 프로세스들이 차례를 지키게 만들어 증상을 임시로 막을 수 있다
flock 으로 잠금을 걸었는데도 운영에서 여전히 자료가 덮어써진다. 가장 먼저 의심할 것은?
- 같은 파일을 만지는 다른 프로그램이 잠금을 잡지 않고 쓰고 있다. flock 은 권고 잠금이다
- flock 은 프로세스가 종료되어도 잠금이 남으므로 잠금이 겹쳐 무효가 됐다
- 파일 시스템이 잠금을 지원하지 않아 flock 호출이 오류 없이 무시됐다
- 잠금을 건 프로세스가 여럿이면 커널이 먼저 잡은 쪽의 잠금을 해제한다