| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > непонятная блокировка |
| Автор: Anark1 17.12.2009, 02:27 | ||||
| Здравствуйте, подзадача - между клиентом и сервером организован именованный канал и очередь сообщений, очередь сообщений для синхронизации, канал - для передачи данных. В клиенте формируется команда (например edit, подразумевающая отправку серверу введенные с клавиатуры данные), далее клиент пишет в канал. Собственно проблема. В самый первый раз все прекрасно работает, клиент пишет, сервер читает, но уже второй раз происходит блокировка.
Все структуры сообщений и константы описаны и работа с очередью выполняется корректно На сервере функционируют несколько процессов, которым нужно передать считанные данные, это реализуется через неименованные каналы, также для внутренней синхронизации используется другая очередь сообщений. Это не имеет прямого отношения к проблеме, написал это для дополнения картины.
fd - массив дескрипторов неименованных каналов. Непонятно вообще почему происходит блокировка. И интересно, что если открывать канал в клиенте с флагом O_NONBLOCK то результат такой же. Уже слегка замучался, буду очень благодарен. |
| Автор: Anark1 17.12.2009, 03:24 |
| Странные вещи происходят. Немного продвинулся в решении проблемы. Оказывается при второй итерации цикла в очередь просто не отправляются\не читаются сообщения. Интересный момент, если выполнить вторую команду (сервер повисает, не может получить это сообщение), потом аварийно "убить" сервер и заново его запустить, то автоматически срабатывает та команда которая должна была быть выполнена в прошлый раз (на которой сервер повис). Я уже совсем не понимаю как такое возможно. |
| Автор: svlary 17.12.2009, 06:19 | ||||
У Вас запись в канал происходит вот столько раз :
А чтение - вот столько :
Почти на 100% уверен, что число запросов на ЧТЕНИЕ превышает число ЗАПИСЕЙ. Вот Ваш сервер и виснет - на запросе чтения. |
| Автор: Anark1 17.12.2009, 10:07 | ||
| svlary, я уже написал, что первый запрос проходит нормально и все читается как нужно. А то что вы привели, это все хорошо. Посмотрите код ниже. Поле размером height*width. Разбивается на полосы, их число wrk_count, высота у всех height, а ширина всех кроме последней wrk_def. У последней полосы ширина wrk_last (так как разбиение может быть неравномерным).
так что тут все в порядке |
| Автор: MAKCim 17.12.2009, 13:42 |
| посмотрите через strace -f, на чем зависает программа и что к этому приводит |
| Автор: Anark1 17.12.2009, 14:07 |
| Провозился, все сводится видимо к некорректности работы очереди сообщений. Эту тему наверное можно закрывать. |
| Автор: svlary 18.12.2009, 06:52 |
Э... Вы намекаете, что неправильно работают ОЧЕРЕДИ ? А Ваша программа - правильная. Так ? |
| Автор: Anark1 21.12.2009, 12:47 | ||
Я намекаю на то, что в cygwin IPC ресурсы реализованы не лучшим образом. У меня не очень большой опыт написания программ под Unix, однако уверен, что мои огрехи виноваты в меньшей степени. Перепроверив код миллион раз в конечном итоге я установил виртуальную машину с FreeBSD. Под FreeBSD все работало корректно, причем код не менял. А косяков в cygwinе было полно. Висела очередь при обмене сообщениями разных размеров, необъяснимые блокировки FIFO (не знаю при чем тут FIFO), при удалении/добавлении назад некоторых операторов взаимодействия с IPC, не влияющих на дальнейшую работу программы иногда вылетало что-то вроеде fork: child хххх - died waiting for dll loading, которое работало до этого. Погуглил на этот счет, не у меня одного такие проблемы. Стоило сразу ставить виртуалку, сэкномоил бы кучу времени и сил. |
| Автор: MAKCim 21.12.2009, 12:49 |
| Anark1, винить cygwin нужно винить только в очень крайнем случае ;) 99% что ошибка у вас |