Рекурсивные мутексы
От: SergH Россия  
Дата: 23.07.12 14:04
Оценка:
Привет,

Есть проектик в котором используются мутексы, обычные, не рекурсивные. Инициализируются через PTHREAD_MUTEX_INITIALIZER. Используются аккуратно: сами мутексы завернуты с сиплюсовый класс, и локер идёт отдельным классом, в конструкторе блокирует, в деструкторе отпускает. Всё работает, проблем нет, дедлоков нет. pthread_mutex_trylock не используется нигде.

Понадобилось в одном месте сделать рекурсивную блокирвку. Ну, не долго думая, переделал в классе мутекса инициализацию. Больше ничего не менял. Оба-на! Всё нахрен сломалось. Ладно, сделал на всякий случай трассировку локов-анлоков -- с трассировкой работает Поэтому уточнить что именно сломалось мне пока сложно, нужна какая-то диагностика. Не крашится.

Как такое может быть вообще? По идее я добавил мутексам возможность, которая, по идее, нигде не используется. Так как иначе это были бы дедлоки. То есть поведение не должно было меняться вообще никак. А оно тем не менее изменилось радикально.

ОС — Убунта. Проблему в итоге решил иначе, без рекурсивных мутексов.
Делай что должно, и будь что будет
Re: Рекурсивные мутексы
От: zaufi Земля  
Дата: 23.07.12 14:36
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Понадобилось в одном месте сделать рекурсивную блокирвку. Ну, не долго думая, переделал в классе мутекса инициализацию. Больше ничего не менял. Оба-на! Всё нахрен сломалось. Ладно, сделал на всякий случай трассировку локов-анлоков -- с трассировкой работает Поэтому уточнить что именно сломалось мне пока сложно, нужна какая-то диагностика. Не крашится.


когда все нахрен сломалось корка была??
если все работает с трассировкой, это наводит на мысль что както изменились тайминги и все по счастливому случаю работает... но проблема все таки есть.

SH>ОС — Убунта. Проблему в итоге решил иначе, без рекурсивных мутексов.


как?

я обычно использую такой паттерн (другой нужды в рекурсивных mutexах испытываю редко):

struct some
{
  mutex mut_;
  ...
  
  void method_1()
  {
    guard g(mut_);
    // do smth method_1 specific...
    ...
    // do some common actions
    common_code(g);

    // do smth method_1 specific...
    ...
  }

  void method_2()
  {
    guard g(mut_);
    // do smth method_2 specific...
    ...
    // do some common actions
    common_code(g);

    // do smth method_2 specific...
    ...
  }

  void common(guard& /*dummy*/)
  {
    // a dummy parameter used only to indicate that this method must be called
    // w/ mutex accured...
  }
};
Re: Рекурсивные мутексы
От: zaufi Земля  
Дата: 23.07.12 14:40
Оценка: 22 (3)
Здравствуйте, SergH, Вы писали:

SH>Понадобилось в одном месте сделать рекурсивную блокирвку. Ну, не долго думая, переделал в классе мутекса инициализацию. Больше ничего не менял. Оба-на! Всё нахрен сломалось. Ладно, сделал на всякий случай трассировку локов-анлоков -- с трассировкой работает Поэтому уточнить что именно сломалось мне пока сложно, нужна какая-то диагностика. Не крашится.


в догонку:
а `valgrind --tool=drd --trace-mutex=yes` что-нить говорит? (еще есть --tool=helgrind) (в смысле не нужно самому трекать lock-unlock и вносить дополнительную задержку, которая приводит к магическому "все рабоатет")...
Re[2]: Рекурсивные мутексы
От: SergH Россия  
Дата: 23.07.12 14:49
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>когда все нахрен сломалось корка была??


Нет, я же написал, что не крашится.
Сломалось в том смысле, что перестало правильно работать. Это TCP-сервер с выделенным потоком на каждого клиента, так вот в версии с рекурсиными мутексами клиенты довольно быстро все отвалились и после того как снова присоединялись работать уже не могли.

Z>если все работает с трассировкой, это наводит на мысль что както изменились тайминги и все по счастливому случаю работает... но проблема все таки есть.


Тут я наврал потому что запутался в тестах. Выяснилось, что с трассировкой я гонял старую версию, они отличаются одной строчкой. С трассировкой тоже всё плохо, т.е. ошибка воспроизводится и может быть я смогу разобраться. Но чуть позже.

Z>как?


Там было действие, которое мне нужно было выполнить атомарно, оно состояло из двух действий, которые уже выполняются атомарно, т.е. под блокировкой. Т.е. нужно было брать блокировку два раза. В итоге немного добавил к одному из действий нужную функциональность и флаг.
Делай что должно, и будь что будет
Re[2]: Рекурсивные мутексы
От: SergH Россия  
Дата: 23.07.12 15:43
Оценка:
Здравствуйте, zaufi, Вы писали:

Z>в догонку:

Z>а `valgrind --tool=drd --trace-mutex=yes` что-нить говорит? (еще есть --tool=helgrind) (в смысле не нужно самому трекать lock-unlock и вносить дополнительную задержку, которая приводит к магическому "все рабоатет")...

Очень много всего говорит, причём в обоих вариантах. Буду разбираться.
Делай что должно, и будь что будет
Re[2]: Рекурсивные мутексы
От: SergH Россия  
Дата: 23.07.12 19:27
Оценка: 1 (1)
Здравствуйте, zaufi, Вы писали:

...

Отгадка: в одном месте было некооректное использование мутекса с условной переменной (pthread_cond_timedwait). С обычными мутексами это _почему-то_ не вызывало проблем, а с рекурсивными вызвало.
valgrind помог, хотя и заспамил (вроде бы) ложными сообщениями о конфликтах.
Делай что должно, и будь что будет
Re: Рекурсивные мутексы
От: MasterZiv СССР  
Дата: 24.07.12 06:17
Оценка:
> нахрен сломалось. Ладно, сделал на всякий случай трассировку локов-анлоков -- с
> трассировкой работает Поэтому уточнить что именно сломалось мне пока сложно,
> нужна какая-то диагностика. Не крашится.

Логирование (запись в файл) может иметь свои мьютексы внутри, и видимо тут они
сработали и засинхронизировали доступ.

> Как такое может быть вообще? По идее я добавил мутексам возможность, которая, по

> идее, нигде не используется.Так как иначе это были бы дедлоки. То есть
> поведение не должно было меняться вообще никак. А оно тем не менее изменилось
> радикально.

Ну рекурсивные и нерекурсивные мьтексы по разному работают, видимо, у тебя
были где-то некорректные алгоритмы, т.е. с гонками, но они не проявлялись
на нерекурсивных мьютексах, а на рекурсивных стали проявляться.
Но это надо код смотреть и никто кроме тебя самого это не найдёт.
Главное -- ты не думай, что мьютексы престали работать, проблема всё равно
в твоей программе.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.