2017-12-29 11 views
1

하나의 스레드가 파일에 기록 (또는 삭제)하거나 다른 파일에서 중복되는 위치에 대해 sendfile()을 동시에 호출합니다.sendfile()이 진행되는 동안 파일이 작성/변경되면 예상되는 동작은 무엇입니까?

여기서 예상되는 동작은 무엇입니까?

또한 내 이해가 정확하다면 sendfile 호출은 소켓 (파일 설명, 위치, 길이)에 레코드를 추가하고 호출자에게 반환됩니다. (아직 소켓의 버퍼에 복사하지 않습니까?) 따라서 파일을 수정하기 전에 sendfile()이 반환됩니다. OS는 파일이 완전히 전송 될 때까지 파일의 존재 여부에 달려 있습니다.

그럼 파일을 보낼 때까지 수정 한 결과는 무엇입니까?

+1

열려있는 파일을 지우더라도 커널의 파일 핸들 (그리고 프로세스의'fd')은 닫힐 때까지 파일을 "활성"상태로 유지합니다. 이것은 또한'fd' 핸들에 영향을 미치지 않고 열린 파일을 "옮길"수있는 이유이기도합니다. 편집으로 인한 경쟁 조건에 대해서는 ... 잘, 그것은 인종입니다. sendfile이 편집 후에 작동하면 편집 된 버전에서 작동합니다. – Myst

+0

쓰기는 실행중인 프로그램, OS 및 심지어 HD 컨트롤러에 의해 버퍼링 될 수 있습니다. 세 명 모두 연속으로. 가장 좋은 방법은 다중 스레드 프로그램에서 동일한 파일을 읽고 쓸 때 원자 가드를 추가하는 것입니다. – usr2564301

+1

@ usr2564301 HD 컨트롤러는 응용 프로그램과 관련이 없습니다. Linux에는 통합 버퍼 캐시가 있으며 모든 프로세스는 동일한 커널 파일 버퍼를 사용합니다. – Barmar

답변

3

예상되는 결과는 예측할 수없는 결과입니다. sendfile()은 원자가 아니므로 파일 설명자에서 read()을 호출하고 소켓 설명자에서 write()을 호출하는 자체 루프를 작성하는 것과 실질적으로 동일합니다. 이 과정에서 파일에 다른 프로세스가 쓰면 이전 내용과 새로운 내용이 혼합되어 나타납니다. 주로 여러 편의 시스템 호출을 필요로하지 않으며 응용 프로그램 버퍼간에 앞뒤로 복사하는 대신 파일 버퍼와 소켓 버퍼간에 직접 복사 할 수 있으므로 훨씬 더 효율적이어야하지만 주로 편의 기능으로 생각하십시오. 이 때문에 취약성 창은 read/write 루프를 수행하는 것보다 작아야하지만 여전히 존재합니다.

이 문제를 방지하려면 쓰기를 수행하는 프로세스와 sendfile()을 호출하는 프로세스 사이에서 파일 잠금을 사용해야합니다.

lock the file 
call sendfile() 
unlock the file 

와 쓰기 과정을 수행해야합니다 : 그래서 순서가 있어야한다

lock the file 
write to the file 
unlock the file 

편집 : 그것은이 간단한처럼 사실

, 그것은 보인다, sendfile() 링크 소켓 때문에 버퍼를 커널에 복사하는 대신 파일 버퍼 캐시에 저장하십시오. sendfile()은 데이터가 전송 될 때까지 기다리지 않으므로 파일을 반환 한 후에 수정하면 전송 된 데이터에 영향을 줄 수 있습니다. 응용 프로그램 계층 승인을 통해 데이터가 모두 수신되었는지 확인해야합니다. 이러한 세부 사항을 설명하는 기사에서 발췌 한 내용은 Minimizing copies when writing large data to a socket을 참조하십시오.

+0

mmap이 같은 방식으로 작동하는지 알고 있습니까? void * p = mmap (fd0); send (fd1, p, 0, len). 따라서 데이터를 전송할 방법이없는 것입니까? 파일을 다시 안전하게 편집하기 시작했습니다. 한 가지 방법은 고객의 의지에 의존 할 수 있습니다. 이것에 대한 아이디어가 있습니까? – vkx

+0

'send()'또는'sendfile()'이 반환 될 때 모든 데이터가 소켓 버퍼에 복사 된 것으로 생각되므로 파일을 수정하는 것이 안전합니다. 나는 당신이'sendfile()'을 호출하는 것과 동시에 파일을 수정하는 다른 프로세스를 가지고 있다고 생각했다. – Barmar

+0

send()는 그런 식으로 작동하지만이 링크를 찾았습니다. 대답에 따르면 sendfile과 mmap이 다르게 작동하지만 답변에서 원래의 종이 링크가 작동하지 않습니다. 이 동작이 확실하지 않습니다. https://stackoverflow.com/questions/20008707/minimizing-copies-when-writing-large-data-to-a-socket – vkx

관련 문제