asio implicit strand i synchronizacja danych

Kiedy czytam kod źródłowy asio, jestem ciekawy, w jaki sposób asio tworzy dane zsynchronizowane między wątkami, nawet niejawny wątek. Są to kody w asio:

io_service :: run

 mutex::scoped_lock lock(mutex_);

  std::size_t n = 0;
  for (; do_run_one(lock, this_thread, ec); lock.lock())
    if (n != (std::numeric_limits<std::size_t>::max)())
      ++n;
  return n;

io_service :: do_run_one

 while (!stopped_)
  {
    if (!op_queue_.empty())
    {
      // Prepare to execute first handler from queue.
      operation* o = op_queue_.front();
      op_queue_.pop();
      bool more_handlers = (!op_queue_.empty());

      if (o == &task_operation_)
      {
        task_interrupted_ = more_handlers;

        if (more_handlers && !one_thread_)
        {
          if (!wake_one_idle_thread_and_unlock(lock))
            lock.unlock();
        }
        else
          lock.unlock();

        task_cleanup on_exit = { this, &lock, &this_thread };
        (void)on_exit;

        // Run the task. May throw an exception. Only block if the operation
        // queue is empty and we're not polling, otherwise we want to return
        // as soon as possible.
        task_->run(!more_handlers, this_thread.private_op_queue);
      }
      else
      {
        std::size_t task_result = o->task_result_;

        if (more_handlers && !one_thread_)
          wake_one_thread_and_unlock(lock);
        else
          lock.unlock();

        // Ensure the count of outstanding work is decremented on block exit.
        work_cleanup on_exit = { this, &lock, &this_thread };
        (void)on_exit;

        // Complete the operation. May throw an exception. Deletes the object.
        o->complete(*this, ec, task_result);

        return 1;
      }
    }

w jego do_run_one odblokowanie muteksu jest przed wykonaniem procedury obsługi. Jeśli istnieje niejawna nić, handler nie będzie wykonywany jednocześnie, ale problem polega na tym, że wątek A uruchamia program obsługi, który modyfikuje dane, a wątek B uruchamia następny program obsługi, który odczytuje dane zmodyfikowane przez wątek A. Bez ochrony mutex , jak wątek B widział zmiany danych wykonane przez wątek A? Odblokowanie muteksu przed wykonaniem procedury obsługi nie powoduje, że relacja między wątkami uzyskuje dostęp do danych uzyskanych przez program obsługi. Kiedy pójdę dalej, wykonanie procedury obsługi używa rzeczy zwanej fenced_block:

 completion_handler* h(static_cast<completion_handler*>(base));
    ptr p = { boost::addressof(h->handler_), h, h };

    BOOST_ASIO_HANDLER_COMPLETION((h));

    // Make a copy of the handler so that the memory can be deallocated before
    // the upcall is made. Even if we're not about to make an upcall, a
    // sub-object of the handler may be the true owner of the memory associated
    // with the handler. Consequently, a local copy of the handler is required
    // to ensure that any owning sub-object remains valid until after we have
    // deallocated the memory here.
    Handler handler(BOOST_ASIO_MOVE_CAST(Handler)(h->handler_));
    p.h = boost::addressof(handler);
    p.reset();

    // Make the upcall if required.
    if (owner)
    {
      fenced_block b(fenced_block::half);
      BOOST_ASIO_HANDLER_INVOCATION_BEGIN(());
      boost_asio_handler_invoke_helpers::invoke(handler, handler);
      BOOST_ASIO_HANDLER_INVOCATION_END;
    }

co to jest? Wiem, że ogrodzenie wydaje się prymitywem synchronizacji obsługiwanym przez C ++ 11, ale to ogrodzenie jest całkowicie zapisane przez samego asio. Czy ten fenced_block pomaga wykonać synchronizację danych?

AKTUALIZOWANY

Po tym jak google i przeczytamto ito, asio rzeczywiście używa prymitywu ogrodzenia pamięci do synchronizowania danych w wątkach, czyli szybciej niż odblokowuje, dopóki program obsługi nie wykona pełnej operacji (różnica prędkości na x86). W rzeczywistości słowo kluczowe volatile Java jest implementowane przez wstawienie bariery pamięci po napisaniu i przed odczytaniem tej zmiennej, aby stało się przed relacją.

Jeśli ktoś mógłby po prostu opisać implementację ogrodzenia pamięci asio lub dodać coś, co przeoczyłem lub źle zrozumiałem, zaakceptuję to.

questionAnswers(1)

yourAnswerToTheQuestion