Стандартная С++ задачка на синхронизацию

Тема в разделе "WASM.HEAP", создана пользователем Green_DiCk, 10 окт 2009.

  1. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    Вот она:

    Код (Text):
    1. if (data_ptr == NULL)
    2. {
    3.         pthread_mutex_lock(&data_mutex);
    4.         if (data_ptr == NULL)
    5.         {
    6.                 data_ptr=initialize_data();
    7.         }
    8.         pthread_mutex_unlock(&data_mutex);
    9. }
    Кто что думает? Я не сильно напрягал мозг (лень), но подвоха не нашёл - вроде должно всегда работать правильно. Хотя чёрт знает, что имелось в виду под "будет работать". Как-то он по-любому "будет работать"...
     
  2. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Этот код не exception safe.
     
  3. Green_DiCk

    Green_DiCk New Member

    Публикаций:
    0
    Регистрация:
    8 июл 2007
    Сообщения:
    338
    _DEN_
    Об этом я как-то не подумал..
    Но составители вопроса вряд ли это имели в виду. В конце-концов многие на С++ вообще без эксепшенов пишут. Здесь наверно вопрос "чисто" на синхронизацию.
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Green_DiCk

    Скорее всего это и имели ввиду. Исключения - неотъемлимая часть языка. Писать на С++ без исключений, всеравно что пить пиво без вяленой воблы :)

    C++ это такой язык, которым вообще мало кто умеет пользоваться :)
     
  5. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    вместо
    if (data_ptr == NULL)
    следует писать
    if (!data_ptr)
    это убирает требование того что у типа data_ptr должен быть оператор ==
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    по теме - все зависит от initialize_data
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    GoldFinch

    Бустовые поинтеры не имеют оператора сравнения с голыми?

    А что от нее может зависить кроме exception safety?
     
  8. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    а вместо ..._unlock хорошо бы RAII
     
  9. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    _DEN_
    там состовители вообще люди интересные :)
    это вопрос из анкеты, недавно здесь постящихся работодателей.
    там первый вопрос был на неправильное освобождение памяти,
    а второй этот.
     
  10. o14189

    o14189 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    320
    тупняк какой-то
    а зачем первое условие то? на "авось" видимо
    этот "кусок" не будет работать как ожидается, но работать будет
    т к pthread_mutex_lock(&data_mutex); явно может выполниться при data_ptr != NULL перед ним
     
  11. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    _DEN_
    мало ли какой это указатель, там же не написано.
     
  12. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    GoldFinch

    Ну я это и имел ввиду под "Этот код не exception safe". Юзать надо boost::scoped_lock;


    o14189
    Чтобы лишний раз не лочить мутекс.


    На самом деле тут еще вопрос в том, является ли обращение к data_ptr тредсейфным :)
     
  13. o14189

    o14189 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    320
    проверка его состояния ведь тоже самое, что и первое условие
     
  14. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    o14189
    двойная проверка - это норм

    _DEN_
    да, у boost::shared_ptr (он же std::tr1::shared_ptr) нету
    operator==(shared_ptr<T>, int)
    и неявного преобразования int в shared_ptr<U> тоже нет
     
  15. o14189

    o14189 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    320
    может быть, только работать будет не так как ожидается, да и мутекс тогда зачем если так проверять, хрень вобщем
     
  16. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    еще можно написать
    Код (Text):
    1. if (!data_ptr)
    2. {
    3.    pthread_mutex_lock(&data_mutex);
    4.    boost::shared_ptr<mutex_t> guard(&data_mutex, &pthread_mutex_unlock);
    5.    if (!data_ptr)
    6.        data_ptr=initialize_data();
    7. }
     
  17. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    *можно boost::shared_ptr<void> вместо boost::shared_ptr<mutex_t>
    чтобы не указывать тип мьютекса
     
  18. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    o14189

    Нет, не тоже самое. После первой проверки (и до второй) указатель мог быть проинициализирован в другом потоке.


    GoldFinch

    Вот этого не понял :)
     
  19. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    _DEN_
    mutex_t* приводится к void* и наоборот
     
  20. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    GoldFinch

    Ну вот этого я и не понял - зачем его приводить к void* ?