Меня очень интересует RCU (чтение-копирование-обновление) в пространстве пользователя и попытка имитировать один через tr1 :: shared_ptr, вот код, в то время как я действительно новичок в параллельном программировании, эксперты помогают мне пересмотреть?Использование shared_ptr для реализации RCU (чтение-копирование-обновление)?
Основная идея заключается в том, что читатель вызывает get_reading_copy(), чтобы получить указатель на текущие защищенные данные (скажем, это поколение один или G1). писатель вызывает get_updating_copy(), чтобы получить копию G1 (скажем, это G2), и только один писатель может войти в критический раздел. После того, как обновление выполнено, автор вызывает update(), чтобы выполнить обмен, и сделайте m_data_ptr, указывающий на данные G2. Текущие читатели и писатель теперь держат shared_ptr (s) G1, и либо читатель, либо автор в конечном итоге освободят данные 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