공유 메모리를 사용하여 프로세스 간 통신이 필요하며 공유 메모리 파일 설명자 또는 공통 파일 설명자 주소를 구조체 또는 벡터/맵을 가리키는 포인터에 할당 할 수 있습니까? 공유 메모리의 주소파일 디스크립터의 주소를 변수에 할당 할 수 있습니까?
Struct A{...};
A* stru = static_cast<A*>(addr); // is this OK?
공유 메모리를 사용하여 프로세스 간 통신이 필요하며 공유 메모리 파일 설명자 또는 공통 파일 설명자 주소를 구조체 또는 벡터/맵을 가리키는 포인터에 할당 할 수 있습니까? 공유 메모리의 주소파일 디스크립터의 주소를 변수에 할당 할 수 있습니까?
Struct A{...};
A* stru = static_cast<A*>(addr); // is this OK?
먼저 예를 들어
, addr
, 당신은 아마 Boost.interprocess보고를 사용해야합니다.
수동 방식의 경우 계속 읽으십시오.
이렇게하려면 구조체에 포인터를 사용하면 안됩니다. 또한 가상 기능이 없어야합니다. 단지 포인터가 아닌 데이터 멤버가있는 구조체 (기본 제공 형식을 의미하며 std::string
또는 std::vector
또는 일반 구조체가 아닌 요소) 및 해당 멤버 함수 (있는 경우)는 해당 데이터에서만 작동하며 비 멤버 함수를 호출하면 안전 할 수 있습니다.
주소가 올바르게 정렬되어 있는지 확인해야합니다.
#include <cstdint>
#include <cassert>
// ...
assert(reinterpret_cast<std::uintptr_t>(addr) % alignof(A) == 0);
당신이 공유 메모리를 생성하는 데 사용하는 방법은 당신이 바이트 단위로 원하는 정렬을 지정할 수 있습니다 경우
는 다음alignof(A)
당신에게 정확한 바이트 수를 줄 것이다 : 당신은 명시 적으로 확인할 수 있습니다.
메모리의 크기는 (적어도 sizeof(A)
해야합니다.)
호환 정렬 및 크기의 경우, 다음의 새로운 배치를 사용하여 해당 메모리의 개체를 만들어야합니다 충분히 커야합니다
을#include <new>
// ...
auto stru = new(addr) A;
stru
은 addr
이 가리키는 메모리에 객체를 만듭니다.
해당 개체에 delete
으로 전화하지 마십시오. 일반적 delete
를 호출하는 위치에서, 당신은 대신 수동으로 소멸자를 호출해야합니다 :
unique_ptr
에서이 객체를 포장해야하기 위해서는
stru->~A();
:
#include <memory>
// ...
auto a_dtor_caller = [](A* obj){ obj->~A(); };
auto stru = std::unique_ptr<A, decltype(a_dtor_caller)>(new(addr) A, a_dtor_caller);
stru
지금있는 unique_ptr
하고 범위를 벗어나면가 관리하는 A
인스턴스가 제대로 파괴 될 것이다.
위의 내용은 한 번만 수행해야합니다. 단지 개체에 액세스해야하는 다른 프로세스는 사용해야합니다
A* stru = static_cast<A*>(addr);
그것은 그들도 결코 delete
목적이나 그 소멸자를 호출 할 수있는 것은 물론이다. 객체를 관리하는 unique_ptr
만이 그렇게해야합니다.
공유 메모리를 확보하려고 할 때 먼저 객체를 파괴해야합니다.코드를 자연스럽게 공유 메모리를 해제하기 전에 unique_ptr
은 "만료"는, 그럼 당신이 수동으로 수행해야합니다하지 않는 경우
stru.reset();
이 개체를 소멸하고 stru
효과적으로 지금 nullptr
이다.
전체적으로 나는 Boost.interprocess를 대신 권장합니다. 오류가 발생하기 쉽습니다.
고마워, 그냥 공유 메모리를 닫고 '삭제'할 때 s = NULL로 만들 수 있습니까? – maidamai
@maidamai 공유 메모리를 해제하기 전에 객체를 파괴하는 방법에 대한 대답을 업데이트했습니다. –
@maidamai 일반 구조체에 대해서만이 작업을 안전하게 수행 할 수 있음을 언급하는 것을 잊어 버렸습니다. 대답에 새로 추가 된 첫 번째 단락을 참조하십시오. –
'A'가 POD이고 'addr'이 어떻게 정렬되는지에 달려 있다고 생각합니다. – melpomene