На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
Страницы: (16) « Первая ... 14 15 [16]  все  ( Перейти к последнему сообщению )  
> Thread-safe shared_ptr , Реализация потоко-безопасного SharedPtr
    Цитата Олег М @
    Думаю заменить ими static CSharedPtrLock. Кто-нибудь может сказать что-то про них?

    Не стоит этого делать. Это функции ядра линукса, используемые для реализации механизмов синхронизации и барьеров по памяти.
      А можно поподробнее, почему? Мне показалось, что они будут неплохой заменой статическому счетчику, который наверняка делает то же самое, только вдвое больше.
        Кстати, кроме всего вышесказанного, там есть ещё одна, довольно интересная тема, а именно - преобразование типов. Насколько мне известно std::shared_ptr не требует наличия виртуального деструктора для типов, достаточно простой возможности приведения.
          Кажется нашёл одну ошибку. Хотя никак не могу осмыслить в чём она состоит и ошибка ли это вообще. Суть её в том, что в операторах присваивания я создаю копию (т.е. блокирую) входящего указателя, но не блокирую себя. Сделал вот такой метод, все операторы сделал через него. Хотя, никакой уверенности, что поможет.

          ExpandedWrap disabled
                void CSharedPtr::reset(CSharedPtr &&sp)
                {
                    CSharedPtr sp1(*this);
                    sp._swap(*this);
                }


          Проявляется ошибка очень редко, как её повторить я не знаю. Описывал её выше - ощущение, что CWeakPtr::lock() возвращает не null для удалённого CSharedPtr.
            Добил-таки! Удалось написать код, при котором эти указатели не работают. Теперь всё нормально.
            Как я и думал, проблема заключалась в методе CSharedPtr::reset(), который теперь выглядит так

            ExpandedWrap disabled
                  void reset(CSharedPtr &&sp)
                  {
                      auto ref = m_ref.load(std::memory_order_acquire);
                      if (m_ref.compare_exchange_strong(ref, sp.m_ref.load(std::memory_order_relaxed)))
                          sp.m_ref.exchange(ref, std::memory_order_relaxed);
                  }


            Кроме того, обнаружил неприятный побочный эффект, который заключался в следующем:
            Есть указатель CSharedPtr sp. В одном потоке постоянно изменяется его значение, sp.reset(new ....), но он никогда не равен null.
            Второй поток копирует этот указатель, CSharedPtr sp2 = sp. Т.е., по идее, sp2 тоже никогда не должен быть null.
            Однако, периодически было, что sp2 == nullptr.

            Тоже починил.
            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
            0 пользователей:


            Рейтинг@Mail.ru
            [ Script execution time: 0,0389 ]   [ 17 queries used ]   [ Generated: 28.03.24, 23:56 GMT ]