Официальный форум СВД Встраиваемые Системы
10 Декабря, 2016, 15:41:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
 
 
 Сайт СВД ВС  Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Многопоточный resmgr и дедлок  (Прочитано 912 раз)
Camarada
Пользователь

Сообщений: 22


« : 05 Февраля, 2014, 10:21:43 »

Ситуация. QNX 6.4.1 x86 1 ядро.
На входе и выходе mqueue.
По devctl даются задания, по devctl же забираются результаты.
Все это делается в двух параллельных потоках (в клиенте).
resmgr содержит две очереди, ограниченные по максимальному/минимальному количеству элементов (mqueue).
Так получается, что задания идут чуть чаще, но блокирование для этого и придумано, чтобы не зависеть от частоты вызовов посылки заданий и получения результатов.
Когда resmgr был однопоточным ситуации дедлока естественны. Так как один поток заблокируется на посылке задания, а другой не вынет вовремя результат, так как менеджер ресурсов занят и выходная очередь также будет переполнена.
Ну я подумал, что надо сделать его многопоточным, чтобы запрос на получение задания обрабатывался параллельно. Виснет все равно.
Причем devctl, который должен вынуть из выходной очереди отправляется из клиента, но в обработчик не попадает.
Перехватил я функцию resmgr_handle, и оказывается, что мое сообщение (призванное вынуть результат из очереди) IO_DEVCTL доставляется, но так как из своей функции я, конечно, вызываю родную resmgr_handle, то виснет именно в ней.

В чем может быть дело, куда дальше рыть. Буду крайне признателен.  Smiley

Да вот трейс потока, который блокируется. Начинает приходить понимание почему, но нет понимания как с этим бороться.
« Последнее редактирование: 05 Февраля, 2014, 10:23:52 от Camarada » Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 652



WWW
« Ответ #1 : 06 Февраля, 2014, 11:17:29 »

Добрый день!

Боюсь, нам потребуется демонстрационный пример в исходных кодах для решения этой проблемы. Прошу Вас написать нам на почту с вложением следующих материалов: исходники примера, pidin в момент блокировки, sloginfo.
Записан

Camarada
Пользователь

Сообщений: 22


« Ответ #2 : 06 Февраля, 2014, 12:31:36 »

Добрый день!

Боюсь, нам потребуется демонстрационный пример в исходных кодах для решения этой проблемы. Прошу Вас написать нам на почту с вложением следующих материалов: исходники примера, pidin в момент блокировки, sloginfo.

Код весь не могу продемонстрировать, ибо много библиотек вмешивается. Попробую написать минимальный пример, на котором воспроизводится. После чего пришлю исходники.
Суть мне ясна. Один поток входит в обработчик io_devctl, там блокируется на mqueue, другой поток пытается выполнить devctl и не входит в обработчик, а повисает на в resmgr_handle, а конкретно на локе аттрибутной записи. Замечание: аттрибутная запись используется одна для всех ocb.
Пока добавлю pidin и sloginfo
Интересующие процессы вот здесь
  499749   1 kov139167917069538  10r RECEIVE     1                           
  499749   2 kov139167917069538  10r CONDVAR     (0x80618f8)                 
  499749   3 kov139167917069538  10r RECEIVE     1                           
  499749   4 kov139167917069538  10r RECEIVE     1                           
  499749   5 kov139167917069538  10r REPLY       24586                       
  499749   6 kov139167917069538  10r CONDVAR     (0xb0376ce0)               
  499749   7 kov139167917069538  10r RECEIVE     1                           
  499750   1 kov139167917745432  10r REPLY       499749                     
  499750   2 kov139167917745432  10r REPLY       499749 
« Последнее редактирование: 06 Февраля, 2014, 12:37:00 от Camarada » Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 652



WWW
« Ответ #3 : 06 Февраля, 2014, 12:53:46 »

Замечание: аттрибутная запись используется одна для всех ocb.

Она уникальна для префикса.
Записан

Camarada
Пользователь

Сообщений: 22


« Ответ #4 : 06 Февраля, 2014, 13:58:45 »

Замечание: аттрибутная запись используется одна для всех ocb.

Она уникальна для префикса.
Имеется ввиду имя устройства? Оно одно у меня.

Набросал пример, который иллюстрирует проблему. Вернее это даже не проблема, о особенность работы, мне нужен совет, как обойти.
Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 652



WWW
« Ответ #5 : 06 Февраля, 2014, 15:06:06 »

Имеется ввиду имя устройства? Оно одно у меня.

Набросал пример, который иллюстрирует проблему. Вернее это даже не проблема, о особенность работы, мне нужен совет, как обойти.


Ради эксперимента попробуйте сделать 2 префикса (устройства) и ассоциировать чтение и запись с разными путями. Соответственно записывающий и читающий клиенты будут иметь разные атрибутивные записи.
Записан

Camarada
Пользователь

Сообщений: 22


« Ответ #6 : 06 Февраля, 2014, 16:02:34 »

Имеется ввиду имя устройства? Оно одно у меня.

Набросал пример, который иллюстрирует проблему. Вернее это даже не проблема, о особенность работы, мне нужен совет, как обойти.


Ради эксперимента попробуйте сделать 2 префикса (устройства) и ассоциировать чтение и запись с разными путями. Соответственно записывающий и читающий клиенты будут иметь разные атрибутивные записи.
Так вся фишка в том, что хочется заставить это работать на одной атрибутной записи.
Но я попробую.
« Последнее редактирование: 06 Февраля, 2014, 16:05:41 от Camarada » Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 652



WWW
« Ответ #7 : 06 Февраля, 2014, 16:17:01 »

Так вся фишка в том, что хочется заставить это работать на одной атрибутной записи.

Вариантов может быть масса:
- несколько префиксов;
- открытие очереди с флагом O_NONBLOCK;
- использование mq_timedreceive()/mq_timedsend();
- создание в сервере опрашивающих потоков и механизм уведомлений;
- создание в сервере опрашивающих потоков и отложенный Reply;
- ...

Суть ситуации заключается в том, что Вы залочили атрибутивную запись в 2х обработчиках. Перед вызовом обработчика libc всегда захватывает ресурс, ассоциированный с атрибутивной записью и освобождает его лишь по окончании обработки (при этом сделали ли Вы Reply клиенту или нет особой роли не играет).
« Последнее редактирование: 06 Февраля, 2014, 16:23:32 от Андрей Докучаев » Записан

Camarada
Пользователь

Сообщений: 22


« Ответ #8 : 06 Февраля, 2014, 21:42:44 »

Вариантов может быть масса:
- несколько префиксов;
- открытие очереди с флагом O_NONBLOCK;
- использование mq_timedreceive()/mq_timedsend();
- создание в сервере опрашивающих потоков и механизм уведомлений;
- создание в сервере опрашивающих потоков и отложенный Reply;
- ...

Суть ситуации заключается в том, что Вы залочили атрибутивную запись в 2х обработчиках. Перед вызовом обработчика libc всегда захватывает ресурс, ассоциированный с атрибутивной записью и освобождает его лишь по окончании обработки (при этом сделали ли Вы Reply клиенту или нет особой роли не играет).
Спасибо за ответы, блокирование мне нужно, не хочется усложнять обработку клиенту, тем более уже договорились о механизме взаимодействия. Да и тогда пул не нужен, если навешивать это все. Разные атрибутные записи придется наверное рассматривать. Механизм уведомлений в рабочем варианте используется, только он уведомляет о том, что в выходной очереди появились данные.
Записан
Андрей Докучаев
Сотрудник СВД ВС
Ветеран

Сообщений: 652



WWW
« Ответ #9 : 07 Февраля, 2014, 09:30:53 »

Разные атрибутные записи придется наверное рассматривать. Механизм уведомлений в рабочем варианте используется, только он уведомляет о том, что в выходной очереди появились данные.

Подумайте о реализации варианта №5 - в обработчике devctl для блокирования по чтению не возвращаете Reply, ставите клиента в очередь. А сами данные возвращаете клиенту из другого потока, который всегда в блокированном на mq_receive() состоянии.

И префикс будет 1 и не будет блокировок на атрибутивной записи.
Записан

Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP © 2002-2016 СВД Встраиваемые Системы.
При использовании материалов сайта ссылка на forum.kpda.ru обязательна.

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines | © Aiwan. Kolobok smiles | Sitemap
Valid XHTML 1.0! Valid CSS!
Сайт СВД ВС

В последний раз google посещал эту страницу 15 Ноября, 2016, 07:49:38