Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: повторная блокировка mutex  (Прочитано 767 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн dronte

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
повторная блокировка mutex
« : 08 Марта 2014, 21:50:29 »
Зравствуйте, как настроить mutex так, чтобы он при повторной попытке блокировки одним и тем же потоком ресурса не блокировал поток (а таким образом получается, что намертво)
конкретно, пример кода:
(Нажмите, чтобы показать/скрыть)
в случае, когда base.next == &base, первые два сообщения выводятся, а третье нет, переписывать все как-то не хочется с логикой, которая будет косвенно судить о том, заблокирован ли каждый из мютексов, trylock тоже не выход, т.к. потом обрабатывать его код, о доступности ресурса, тут же и так все предельно просто, если ресурс заблокирован уже и так потоком, который пытается еще раз заблокировать, чего еще надо-то? пусть пропускает, это ж не семафор ...

догадываюсь, что это можно решить каким-то аттрибутом при инициализации мютекса
« Последнее редактирование: 08 Марта 2014, 21:55:34 от dronte »

Оффлайн Peter_I

  • Старожил
  • *
  • Сообщений: 3037
    • Просмотр профиля
Re: повторная блокировка mutex
« Ответ #1 : 08 Марта 2014, 23:27:20 »
Для этого mutex должен быть создан как рекурсивный,
но я подозреваю, что у вас алгоритм работы не продуман,
если возникают такие вопросы.
И в чём трудность обработки результата trylock()? Совершенно нормальная практика.
« Последнее редактирование: 09 Марта 2014, 16:00:49 от Peter_I »
Пётр.

Оффлайн dronte

  • Автор темы
  • Любитель
  • *
  • Сообщений: 98
    • Просмотр профиля
Re: повторная блокировка mutex
« Ответ #2 : 08 Марта 2014, 23:58:48 »
Непродуман - не совсем то, просто мне нужен полулист-полумножество, который будет оперировать аргументами и переменными работы потоков, которые плодит сервер базы данных, к элементам которого (листа) будет иметь возможность обращаться каждый из потоков, которые в свою очередь делают действия в непредпологаемом порядке (кто знает, что и в какой последовательности захочет пользователь?), поэтому с одной стороны, если пользователь начал работать с элементом, то логично заблокировать чтение и запись в него другим (вдруг кто его удалит, пока этот с ним работает?), но далее получается, что во всех функциях к которым вдруг обратится пользователь нужно делать блокировку через try ... и каждый раз обрабатывать ее ответ ... ну в общем много дописывать одно и тоже, ладно, можно переписать все на макрос ... но тут тогда куча операций передвижений по листу и каждый раз if ... тяжелова-то как-то будет мне кажется ...

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

UPDATE: обнаружился странный результат, переписал все на trylock, оказалось, что не определены константы возвращаемых значений, вроде EBUSY, EAGAIN например:
(Нажмите, чтобы показать/скрыть)

UPDATE2: в руководстве man нет страниц связанных с pthread_mutex_t как-либо вообще, как достать? об pthread_attr_set* и pthread_create есть, а такого почему-то нет, странно ... хотя есть ощущение, что половины манов вообще не хватает ...

UPDATE3: решил ради эксперимента подключить библиотеку errno.h к этому исходнику - на удивление помогло, думал там только сама константа errno и всякое вроде perror
« Последнее редактирование: 09 Марта 2014, 02:00:00 от dronte »

Оффлайн Peter_I

  • Старожил
  • *
  • Сообщений: 3037
    • Просмотр профиля
Re: повторная блокировка mutex
« Ответ #3 : 09 Марта 2014, 16:21:58 »
Вам не надо думать, что такое pthread_mutex_t, достаточно подключить pthread.h
и следовать man'ам на функции. Ещё должен быть установлен пакет glibc-doc.

Что касается трудностей с блокировкой - mutex должен блокироваться один раз,
когда пользователь начинает работу с объектом, и один раз освобождаться -
когда пользователь прекращает работу с ним. Этого достаточно, т.к. в другом
потоке этот mutex уже не будет захвачен до тех пор, пока 1-й поток его
не освободит.
Т.е. для каждого пользователя или для каждой попытки работы с элементом
должен запускаться отдельный поток, а внутри одного и того же потока
многократный захват мьютекса не имеет смысла, т.к. это блокирует поток.
mutex для этого и предназначен.

В одном и том же потоке надо ждать, когда mutex освободится,
т.е. обрабатывать значение, возвращаемое trylock.
Например, периодически повторять попытку захвата или же вообще
не допускать такой ситуации.
« Последнее редактирование: 09 Марта 2014, 20:24:18 от Peter_I »
Пётр.

 

Страница сгенерирована за 0.038 секунд. Запросов: 25.