나는 사용자 공간 RCU (read-copy-update)에 매우 흥미가 있으며, tr1 :: shared_ptr을 통해 시뮬레이트하려하고 있는데, 여기에 코드가있다. 동시 프로그래밍의 초보자이지만, 전문가가 나를 도울 수있게 도와 주나요?shared_ptr을 사용하여 RCU를 구현 (읽기 - 복사 - 업데이트) 하시겠습니까?
기본적인 아이디어는 reader가 현재 보호 된 데이터의 포인터를 얻기 위해 get_reading_copy()를 호출한다는 것입니다 (세대 1 또는 G1이라고 가정 해 봅시다). writer는 get_updating_copy()를 호출하여 G1의 복사본을 얻습니다 (G2라고 가정 해 봅시다). 단 하나의 작성자 만 중요한 섹션에 들어갈 수 있습니다. 업데이트가 완료되면 작성기는 update()를 호출하여 스왑을 수행하고 m_data_ptr이 G2 데이터를 가리 키도록합니다. 진행중인 독자와 작가는 이제 G1의 shared_ptr (s)를 보유하고 있으며 독자 또는 작성자가 결국 G1 데이터 할당을 해제합니다.
새로운 독자는 G2에 대한 포인터를 얻고 새로운 작성자는 G2 사본을 가져옵니다 (G3이라고 가정 해 봅시다). G1이 아직 출시되지 않았기 때문에 여러 세대의 데이터가 공존 할 수 있습니다.
template <typename T>
class rcu_protected
{
public:
typedef T type;
typedef const T const_type;
typedef std::tr1::shared_ptr<type> rcu_pointer;
typedef std::tr1::shared_ptr<const_type> rcu_const_pointer;
rcu_protected() : m_is_writing(0),
m_is_swapping(0),
m_data_ptr (new type())
{}
rcu_const_pointer get_reading_copy()
{
spin_until_eq (m_is_swapping, 0);
return m_data_ptr;
}
rcu_pointer get_updating_copy()
{
spin_until_eq (m_is_swapping, 0);
while (!CAS (m_is_writing, 0, 1))
{/* do sleep for back-off when exceeding maximum retry times */}
rcu_pointer new_data_ptr(new type(*m_data_ptr));
// as spin_until_eq does not have memory barrier protection,
// we need to place a read barrier to protect the loading of
// new_data_ptr not to be re-ordered before its construction
_ReadBarrier();
return new_data_ptr;
}
void update (rcu_pointer new_data_ptr)
{
while (!CAS (m_is_swapping, 0, 1))
{}
m_data_ptr.swap (new_data_ptr);
// as spin_until_eq does not have memory barrier protection,
// we need to place a write barrier to protect the assignments of
// m_is_writing/m_is_swapping be re-ordered bofore the swapping
_WriteBarrier();
m_is_writing = 0;
m_is_swapping = 0;
}
private:
volatile long m_is_writing;
volatile long m_is_swapping;
rcu_pointer m_data_ptr;
};
나는 읽기 및 업데이트를 보호하기 위해 rw_mutex를 사용해야합니다. 검토를 위해 [email protected]에게 감사드립니다 ... – yongsun