2010-05-17 4 views
2

많은 동시 액세스를 프로세스별로 처리 할 수 ​​있어야하는 응용 프로그램을 작성하고 있습니다. 따라서 뮤텍스 나 락을 적용해서는 안됩니다.크로스 플랫폼 및 교차 프로세스의 원자 적 쓰기가 파일에 기록됩니다.

잠금을 최소화하려면 파일을 "추가 전용"으로 설계하므로 모든 데이터가 먼저 디스크에 추가되고 주소가 정보를 가리키고 있습니다. 업데이트 됨은 새로운 것을 참조하도록 변경됩니다. 그래서 새로운 주소를 참조하도록이 하나의 int를 변경하기 위해서만 작은 잠금 시스템을 구현해야합니다. 가장 좋은 방법은 무엇입니까?

주소 앞에 플래그를 두는 것에 대해 생각했습니다. 설정 될 때까지 독자는 출시 될 때까지 스핀 록을 사용합니다. 하지만 원자력이 전혀 아닌 것 같아? 예 :

  • 리더가 플래그를 판독하고, 동시에에
  • 해제하고, 작가는 플래그를 기록하고 불일치 값을 읽을 수있다 INT
  • 독자의 값을 변경!

나는 잠금 기술을 찾고 있지만 스레드 찾기 기술이나 필드가 아닌 전체 파일을 잠그는 것이 모두 발견됩니다. 이것을 할 수 없습니까? 추가 전용 데이터베이스가 어떻게 이것을 처리합니까?

편집 : 내가 어떻게 append-only db (couchDB)를하는지 보았는데 파일에 대한 쓰기를 직렬화하기 위해 스레드를 사용하는 것 같습니다. 즉, 파일 시스템 잠금으로 전체 파일을 잠그지 않고도 sqlite처럼 임베드 가능하게 만들 수는 없습니까?

감사합니다. Cauê

+0

2 개의 잠금 장치를 작성하고 작성한 것보다 역순으로 읽으면 추악한 해결책을 얻을 수 있습니까? – Waneck

답변

1

파일 시스템의 추가 의미에주의하십시오. 아마도 원자 추가 작업을 제공하지 않습니다.

하나의 옵션은 파일을 공유 메모리로 메모리 맵핑 (mmap) 한 다음 포인터에 대한 비교 및 ​​교체와 같은 아토믹 메모리 작업을 수행하는 것입니다. 귀하의 성공 여부는 귀하의 OS가 그러한 운영 방식을 가지고 있는지 여부에 달려 있습니다 (Linux, OSX do).

올바른 (비록 그것이 빠르지는 않지만) 당신이 원하는 것을 이루는 방법은 rename입니다. 이것은 대부분의 파일 시스템에서 원자 파일 작업입니다. 최신 파일을 공식 파일 위치에 보관하십시오. 데이터를 업데이트하려면 새 데이터를 임시 파일에 기록한 다음 임시 파일의 이름을 공식 위치로 바꿉니다.

+0

답변 해 주셔서 감사합니다! 나는 mmap도 파일에 쓸 수 있다는 것을 몰랐다. 윈도우 상당 (MapViewOfFile)이 예상대로 작동하면 옵션이 될 수도 있습니다. 그러나 비교 및 ​​스왑 기능을 사용하는 프로세서 간 방법이 있는지 여부는 알 수 없습니다. 추가 의미론에 대해서, 나는 정상적인 파일 시스템 파일 잠금이이 경우에 잘 작동한다고 생각하지 않습니까? 이름 바꾸기가 문제가되지 않습니다. 그것은 내가 작업하고있는 데이터베이스 프로토 타입이며 매우 큰 파일과 지속적인 쓰기를 처리해야합니다. – Waneck

+0

페이지를 배열에 mmap하고 쓰기가 필요한 경우 비교 및 ​​스왑을 사용하는 것이 좋습니다. mmap 페이지가 느려지겠습니까? mmap은 원자 단위로 보장됩니까? 나는 그것이라고 말하는 어떤 언급도 발견하지 못했지만 그것도 아니라고 말하는 것은 아무것도 없다! – Waneck

+1

나에게 좋은 워크 플로처럼 들립니다. mmap'd 페이지는 느리지 만 (적어도 Linux에서는), 실제로 복사를 피하기 때문에 읽기/쓰기를 사용하는 것보다 빠릅니다 (가상 메모리는 파일 시스템 캐시의 페이지에 직접 매핑됩니다). Windows에서이 스키마가 전혀 작동하지 않아야합니다. 두 프로세스의 두 mmap'd 영역은 비교 및 ​​스왑이 작동하기 위해 동일한 실제 메모리에 매핑해야합니다. mmap 호출이 원자 단위이거나 아닐 경우 사용자 상황과 관련이 없습니다. 당신이 필요로하는 유일한 원 자성은 이미 mmap 된 메모리에 대한 비교 - 교환의 연산입니다. –

1

이와 같은 작업이 필요할 때 일반적으로 데이터를 얻기 위해 다른 프로세스의 다중 연결을 허용하는 프로세스를 작성합니다. 이 로깅 프로세스는 동일한 위치로 여러 번 기록 할 위험없이 모든 데이터를 쓰는 단일 파일 포인터를 유지 관리 할 수 ​​있습니다.

로깅 프로세스의 각 스레드는 데이터를 생성 한 프로세스를 차단하지 않고 새 입력을 수신 대기열로 전송합니다. 로깅 할 데이터를 생성하는 스레드에서이 작업 (디스크에 쓰기)을 시도하면 결국에는 잠금 작업을 수행해야하는 위치에 놓이게되고 필요한 성능이 저하됩니다.

+0

답변 해 주셔서 감사합니다. 그러나 여전히 독자가 writer 프로세스가 쓰는 데이터를 읽는 경우 - int 포인터 일지라도 여전히 일관성없는 상태로 catch 할 수 있습니까? 또한이 종류의 프로세스 통신을 사용하지 않는 것이 좋습니다.이 데이터베이스 프로토 타입을 sqlite와 같이 삽입 가능하게 만들고 싶습니다. – Waneck