2010-07-07 3 views
12

나는 프로세스를 상당히 과장되게 활용 한 메모리 매핑 파일에 의해 뒷받침되는 스레드 안전 큐에서 작업하고있었습니다. 나는 코드 리뷰를 위해 그것을 제출했고,이 행성보다 많은 경험을 가진 개발자는 boost :: interprocess가 "황금 시간대 준비가되었다"고 느끼지는 않는다고 말했고 나는 단지 pthread를 직접 사용해야한다고 말했다.boost :: interprocess는 주요한 시간 동안 준비 되었습니까?

나는 그것이 대부분 FUD라고 생각합니다. 나는 개인적으로 upgradable_named_mutex 나 boost :: interprocess :: deque와 같은 것들을 다시 구현하는 것은 우스꽝스러운 일이라고 생각하지만 다른 사람들이 생각하는 것을 알고 싶다. 나는 그의 주장을 뒷받침 할 어떤 데이터도 찾을 수 없었지만 아마도 나는 단지 지식이 없거나 순진한 사람 일 뿐이다. Stackoverflow 날 계몽!

답변

19

나는 프로젝트를 위해 boost :: interprocess를 사용하려고 시도하고 혼란스러운 감정으로 나갔다. 내 안타까운 것은 boost :: offset_ptr의 디자인과 NULL 값을 처리하는 방법이다. 즉, boost :: interprocess는 NULL 포인터를 실수로 진단하는 것을 어렵게 만들 수있다. 문제는 공유 메모리 세그먼트가 프로세스의 주소 공간 중간에 매핑된다는 것입니다. 즉, 역 참조 할 때 "NULL"offset_ptr이 유효한 메모리 위치를 가리 키므로 응용 프로그램 이 아닙니다. segfault . 즉, 응용 프로그램이 마침내 중단 될 때 오류가 발생하면 오랜 시간이 걸릴 수 있으므로 디버깅하기가 까다로울 수 있습니다.

하지만 악화됩니다. ::: 프로세스 간 사용을 향상시키는 뮤텍스 및 조건은 내부적으로 세그먼트 시작 부분에 저장됩니다. 따라서 실수로 some_null_offset_ptr-> some_member에 쓰면 boost :: interprocess 세그먼트의 내부 기계 장치를 덮어 쓰게되고 완전히 이상하고 이해하기 어려워집니다. 여러 프로세스를 조정하고 가능한 경쟁 조건을 처리하는 코드를 작성하는 일은 독자적으로 힘들 수 있으므로 두려운 일이 있습니다.

필자는 최소한의 공유 메모리 라이브러리를 작성하고 POSIX mprotect 시스템 호출을 사용하여 공유 메모리 세그먼트의 첫 번째 페이지를 읽을 수없고 쓸 수 없게 만들었습니다. NULL 버그가 즉시 나타납니다 (메모리 페이지가 낭비되는 등의 문제가 있습니다. 임베디드 시스템을 사용하지 않는 한 작은 희생이 가치가있다). boost :: interprocess를 사용해 볼 수도 있지만 여전히 수동으로 mprotect를 호출하면 부스트가 세그먼트의 시작 부분에 저장하는 내부 정보에 쓸 수 있기를 기대하기 때문에 작동하지 않습니다.

마지막으로 offset_ptr은 공유 메모리 세그먼트 내의 포인터를 동일한 공유 메모리 세그먼트의 다른 지점에 저장한다고 가정합니다. 여러개의 공유 메모리 세그먼트를 가질 것이라는 것을 안다면 (나는 쓰기 가능한 세그먼트와 1 개의 읽기 전용 세그먼트를 가지고 있기 때문에 이것이 가능할 것입니다), 포인터를 서로 저장할 것이기 때문에, offset_ptr은 여러분의 방법으로 얻습니다. 수동 변환을 많이해야합니다. 내 공유 메모리 라이브러리에서 템플릿을 만들었습니다. SegmentPtr<0>은 하나의 세그먼트에 대한 포인터가 될 것이고, SegmentPtr<1>은 다른 세그먼트에 포인터가 될 수 있습니다 (예 : 번호를 알고있는 경우에만이 작업을 수행 할 수 있습니다). 컴파일 타임에 세그먼트 수).

NULL 오류를 추적하고 잠재적으로 다른 세그먼트에 포인터를 혼합하는 데 소요되는 추가 디버깅 시간 대 모든 것을 직접 구현하는 데 드는 비용을 감안해야합니다 (후자는 반드시 문제가되지 않습니다). 나 자신을 구현하는 것이 가치가 있었지만, 데이터 구조를 많이 사용하지 않고 :: interprocess가 제공하는 것이므로 분명히 가치가 있었다. 라이브러리가 앞으로 오픈 소스가 될 수 있다면 링크로 업데이트 하겠지만 지금은 숨을 참지 마십시오 p

당신의 동료와 관련하여 : boost :: interprocess 자체에서 어떤 불안정성이나 버그를 경험하지 마십시오. 나는 그 디자인이 당신 자신의 코드에서 버그를 찾기가 더 어렵다고 생각한다.

5

우리는 약 6 개월 동안 boost :: interprocess 공유 메모리와 interprocess.synchronization_mechanisms.message_queue을 사용하여 안정적이고 안정적이며 사용하기 쉬운 코드를 발견했습니다.

우리는 상당히 단순한 고정 크기 구조체 (12 개 영역의 크기는 2 + gb이지만)에서 데이터를 유지하고 boost :: interprocess 예제 코드를 그대로 사용했으며 거의 ​​문제가 없었습니다.

windows와 함께 boost :: interprocess를 사용할 때주의해야 할 두 가지 항목을 찾았습니다.

  1. 검토 Boost Shared Memory & Windows. 기본 #include <boost/interprocess/shared_memory_object.hpp> 객체를 사용하는 경우 Windows를 먼저 재부팅해야만 메모리 매핑 된 영역의 크기를 늘릴 수 있습니다. 이는 부스트가 파일 백업 저장소를 사용하는 방식 때문입니다.
  2. message_queue 클래스는 기본 shared_memory_object를 사용합니다. 따라서 메시지 크기를 늘려야 할 경우 Windows를 다시 시작하십시오.

저는 boost :: interprocess 문제에 대한 Joseph Garvin의 게시물이 유효하지 않았다고 말하려고하지 않습니다. 나는 우리 경험의 차이점이 도서관의 다른 측면을 사용하는 것과 관련이 있다고 생각한다. 나는 boost :: interprocess에서 안정성 문제가없는 것으로 보인다고 동의한다.

+4

Windows를 재부팅하는 대신 응용 프로그램을 다시 시작 하시겠습니까? 귀하의 링크에서 Windows를 재부팅하는 방법에 대해 아무 것도 보지 못하거나 파일을 백업 저장소로 사용하여 필요한 O_o를 생성하는 방법을 이해할 수 없습니다. –