2010-06-18 4 views
8

리눅스에서 공유 메모리를 사용하는 두 개 이상의 프로세스간에 데이터를 교환하는 메커니즘을 개발 중입니다. 문제는 공유 메모리 자체에서 데이터 무결성을 유지하는 데 필요한 몇 가지 수준의 동시성 제어입니다. 언젠가 또는 다른 프로세스가 죽거나 충돌 할 수 있다고 생각하면서 일반적인 잠금 메커니즘은 메모리를 남겨 둘 수 있기 때문에 작동하지 않습니다. "잠긴"상태이고 죽은 직후에 다른 프로세스가 잠금 장치가 해제 될 때까지 대기하는 상태로 만듭니다.공유 메모리 일관성을위한 잠금 메커니즘

그래서 몇 가지 연구를 통해 System V 세마포어에 SEM_UNDO 플래그가있어 프로그램이 실패 할 때 잠금 상태를 되돌릴 수 있다는 것을 알았지 만 작동하지는 않습니다. 또 다른 옵션은 공유 메모리를 사용할 수있는 모든 프로세스에서 PID를 모니터링하고 문제가 발생할 경우이를 제어합니다.하지만 이것이 내 문제에 대한 올바른 접근 방법인지 확실하지 않습니다.

어떤 아이디어 ?? :)

편집 : 설명을 위해, 우리의 애플 리케이션은 가능한 가장 작은 대기 시간과 일종의 IPC 메커니즘이 필요합니다. 그래서 저는이 요구 사항을 처리 할 수있는 메커니즘에 대해서도 개방적입니다.

+0

또 다른 대안은 공유 메모리를 사용하지 않는 것입니다. 프로그래머들에게 끔찍한 매혹을 안겨주는 것을 결코 이해하지 못했습니다. 다른 IPC 메카니즘들 (공유 메모리에 사전 빌드되고 테스트 된 것들)이 많이 있습니다. 그래서 그들을 사용하지 않으시겠습니까? –

+1

성능 향상을 위해. 우리의 애플리케이션은 마이크로 초 대기 시간 동안 작동해야합니다. 이 성능을 달성 할 수있는 IPC 메커니즘이 있습니까? – scooterman

+0

@scooterman 어떤 실시간 리눅스 버전을 사용하고 있습니까? –

답변

0

내가 사용하는 소스가 SEM_UNDO에서 작동한다는 보장이 없다는 것을 알고 싶다면 궁금 할 것입니다. 나는 전에 그것을 들었다. 나는 리눅스의 SYSV IPC가 일반적으로 버그가 있다고 주장하는 기사를 읽은 것을 기억하는 것 같다. 그러나 그것은 꽤 오래 전이었다. 나는 당신의 정보가 시간 과거의 유물인지 궁금해.

또 다른 고려해야 할 점은 SYSV 세마포어에 세마포어 작업을 수행하기위한 마지막 프로세스의 PID를 알려주는 기능이 있다는 것입니다. 응답하지 않으면 잠금을 보유하고있는 프로세스가 아직 살아 있는지 여부를 쿼리 할 수 ​​있어야합니다. 어떤 프로세스 (잠금 장치를 가지고있는 프로세스뿐만 아니라)가 세마포어로 조작 할 수 있기 때문에 당신은 그런 식으로 통제 할 수 있습니다.

마지막으로 메시지 대기열에 대해 설명하겠습니다. 속도 요구 사항에 맞지 않을 수도 있지만 일반적으로 공유 메모리보다 훨씬 느립니다. 본질적으로 SM은 어쨌든 SM을 사용하여 수동으로해야하는 모든 작업을 수행하지만 OS는이 작업을 모두 커버합니다.동기화, 원 자성, 사용 용이성 및 철저한 테스트를 거친 메커니즘을 통해 거의 모든 속도를 얻을 수 있습니다.

+0

메시지 대기열로 전환했기 때문에이를 받아 들일 것입니다. 감사합니다 – scooterman

2

프로그램이 실패 할 때 정리가 보장되는 것은 거의 없습니다. 여기 내 마음에 오는 유일한 것은 링크 수입니다. 열린 파일 기술자는 기본 inode의 링크 카운트를 증가시키고 해당 닫기는 프로그램이 실패 할 때 강제 종료를 포함하여이를 감소시킵니다.

그래서 프로세스는 모두 공통 파일을 (가 공유 메모리 세그먼트에 대한 작동하는지 기억이 안나요) 열 수 카운트가 어디 말아야 감소하면 당신은 알람의 어떤 종류를 실행할 수 있습니다. 예를 들어 평범한 대기 시간을 사용하는 대신 루프에서 프로세스가 일정 시간 대기 (예 : 1 초)를 수행하고 일순간에 잘못되었을 때 링크 수를 조사하여 알림을받을 수 있습니다.

+0

퓨 텍스를 올바르게 사용하면 커널이 청소합니다 – Spudd86

+0

질문은 posix로 표시됩니다. IIRC 퓨 텍스는 순수한 리눅스 구조이며 다른 POSIX 시스템으로 이식 할 수 없습니다. –

+0

몇 가지 생각을 해보면 실제로 POSIX 호환 잠금 구조가 있으며 프로세스 종료시 정리가 보장됩니다. fcntl을 통한 권고 파일 잠금.그들은 사용하기가 약간 까다 롭습니다 (같은 inode에있는 fd가 프로세스의 스레드에 의해 닫히면 잠금을 풀어줍니다.)하지만 커널 공간에서 완전히 실현되고 실제로 디스크에 기록되는 것은 없습니다. –

1

세마포어가 프로세스를 깨끗하게 처리 할 수 ​​없다고 말했을 때 나는 조금 놀랐다. 그런 종류의 지원은 상당히 근본적인 것처럼 보입니다! semop man page를 우분투 10.4 시스템과 웹 here 모두에서 보면 괜찮을 것이라고 생각하는 것 같습니다. SEM_UNDO 횟수를 저장하는 데 사용되는 메모리가 커널 공간에 저장되어 잘못된 메모리 쓰기가 발생하지 않도록하는 것이 좋습니다.

신뢰할 수있는 세마포 잠금 메커니즘조차도 문제를 완전히 해결하지 못할 수도 있습니다. 트랜잭션 처리를 위해 잠금을 사용하는 경우 트랜잭션이 충돌하기 전에 부분적으로 중지되는 상황을 처리하고 다른 프로그램이 데이터 구조에 액세스 할 수있게해야합니다.

+0

죄송합니다, 내가 읽은 곳의 출처를 찾지 못했습니다. 시스템 IV 세마포어에는 프로세스에서 보유 할 수있는 약 37,000 개의 SEM_UNDO 구조체의 한계가 있기는하지만 어쨌든 내 응용 프로그램이이 양의 메시지를 매우 빠르게 작성할 수 있기 때문에 작동하지 않습니다. 어쨌든 고마워. – scooterman

1

당신은 당신이이 출시 커널을 받고 대해 이야기부터 직접 particularaly 두 번째를 http://people.redhat.com/drepper/futex.pdfhttp://lxr.linux.no/#linux+v2.6.34/Documentation/robust-futexes.txthttp://www.kernel.org/doc/man-pages/online/pages/man7/futex.7.htmlhttp://www.kernel.org/doc/man-pages/online/pages/man2/futex.2.html를 참조 futexes에 사용하려고 수 또한

(http://linux.die.net/man/3/pthread_mutexattr_setpshared)

pthread_mutexattr_setpshared 공유 메모리에서의 pthread 뮤텍스를 사용할 수 있습니다 그것을 지키고있는 프로세스가 죽을 때.

또한 pthreads locks/CVs를 강력하게 만들 수 있다고 생각합니다. 강력한 잠금을 처리하는 데 필요한 모든 것들이 당신을 위해 이루어졌습니다. (심지어 현대적인 배포판에서도 강력한 futex를 사용해야합니다. pthread_mutex IIRC에 대한 http://lxr.linux.no/#linux+v2.6.34/Documentation/robust-futexes.txt에 기술은 아주 잠시 동안 커널에있었습니다,하지만 당신은 당신이) 당신의 pthread_mutex는 강력한 그래서

3

를 만들기 위해 아무것도 할 필요가 일부 연구 나는 일을하지 않는 확인 할 수 있습니다 때문에 시스템 V 세마포어에 SEM_UNDO 플래그가있어 프로그램이 실패 할 때 잠금 상태를 되돌릴 수 있다는 것을 알았지 만 작동하지는 않습니다.

SEM_UNDO는 프로세스가 충돌하면 세마포어를 잠금 해제합니다. 프로세스가 공유 메모리의 손상으로 인해 추락하면 세마포어가 수행 할 수있는 것이 없습니다. OS는 공유 메모리의 상태를 실행 취소 할 수 없습니다.

공유 메모리의 상태를 롤백 할 수 있어야한다면 스스로 구현해야합니다. 나는 그것을 다루는 적어도 두 가지 모델을 보았다.

공유 메모리의 내용을 수정하기 전에 첫 번째 모델은 구조의 스냅 샷을 작성하여 공유 메모리의 목록에 저장했습니다. 다른 프로세스가 잠금을 얻을 수 있었고 목록이 비어 있지 않으면 프로세스가 변경되었을 수도있는 모든 작업을 취소했습니다.

두 번째 모델은 로컬 메모리에 shm 구조체의 복사본을 만들고 전체 트랜잭션에 대해 잠금을 잠그는 것입니다. 트랜잭션이 커밋 될 때 잠금을 해제하기 전에 로컬 메모리에서 공유 메모리로 구조를 복사하기 만하면됩니다. sigprocmask()을 사용하면 복사 중에 앱이 다운되는 확률이 낮아지며 외부 신호에 의한 간섭이 차단 될 수 있습니다. (예를 들어, 4 개의 동시 프로세스에 의해 액세스되는 shm의 10Mln 레코드에 대한 1000 개의 잠금 집합을 가진 테스트를 보았습니다.)

+0

아주 흥미로운 것들. 고맙습니다! – scooterman