Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> непонятная блокировка, fifo 
V
    Опции темы
Anark1
Дата 17.12.2009, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 622
Регистрация: 15.12.2006
Где: RF -> Moscow

Репутация: нет
Всего: 11



Здравствуйте,
подзадача - между клиентом и сервером организован именованный канал и очередь сообщений, очередь сообщений для синхронизации, канал - для передачи данных.
В клиенте формируется команда (например edit, подразумевающая отправку серверу введенные с клавиатуры данные), далее клиент пишет в канал.
Собственно проблема. В самый первый раз все прекрасно работает, клиент пишет, сервер читает, но уже второй раз происходит блокировка.

Код

client:
#define FIFO_NAME "srv_fifo\0"
...
fifo = open(FIFO_NAME,O_RDWR);
...

while (ok)
    {
        printf("Введите команду\n");
        scanf("%s",menu);
        if (memcmp(menu,edit,strlen(menu)) == 0) //проверка, что введенная команда является edit
            {    
                msg.type = SC; //инициализация сообщения для сервера
                msg.code = MSG_EDIT;
                msgsnd(msid,(msg_buf*)(&msg),sizeof(int),0); //отправка сообщения
                printf("Введите элементы поля\n");
                for (i=1;i<=height*width;i++)
                {
                    scanf("%d",&num);
                    write(fifo,&num,sizeof(int)); //блокировка возникает во время второй итерации цикла
                }
            }
...


Все структуры сообщений и константы описаны и работа с очередью выполняется корректно

На сервере функционируют несколько процессов, которым нужно передать считанные данные, это реализуется через неименованные каналы, также для внутренней синхронизации используется другая очередь сообщений. Это не имеет прямого отношения к проблеме, написал это для дополнения картины.

Код

server:

#define FIFO_NAME "srv_fifo\0"    
...
mkfifo(fifo_name, S_IFIFO | 0666);
fifo = open(FIFO_NAME, O_RDONLY);
...
msgrcv(msid,(msg_buf *)(&msg),sizeof(int),SC,0); //принимаем сообщение
switch (msg.code)
{
    case MSG_EDIT:
                ...
        LoadFromFIFO(fd, fifo,wrk_def,wrk_last,wrk_count,height); //пропущен блок синхронизации дочерних процессов
                ...

//функция LoadFromFIFO считывает данные из нашего именованного канала и распределяет их по неименованным каналам
void LoadFromFIFO(int * fd, int fifo, int wrk_def, int wrk_last, int wrk_count, int height)
{
    int i,j,num;
    for (i=1;i<wrk_count;i++)
    {
        for (j=1;j<=height*wrk_def;j++)
        {
            read(fifo,&num,sizeof(int));
            write(fd[2*(i-1)+1],&num,sizeof(int));
        }
    };
    
    for (j=1;j<=height*wrk_last;j++)
    {
        read(fifo,&num,sizeof(int));
        write(fd[2*(wrk_count-1)+1],&num,sizeof(int));
    };
}


fd - массив дескрипторов неименованных каналов.
Непонятно вообще почему происходит блокировка. И интересно, что если открывать канал в клиенте с флагом O_NONBLOCK то результат такой же.
Уже слегка замучался, буду очень благодарен.


Это сообщение отредактировал(а) Anark1 - 17.12.2009, 02:29


--------------------
Enjoy yourself, still you can...;)

user posted image

user posted image
PM MAIL ICQ   Вверх
Anark1
Дата 17.12.2009, 03:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 622
Регистрация: 15.12.2006
Где: RF -> Moscow

Репутация: нет
Всего: 11



Странные вещи происходят. Немного продвинулся в решении проблемы. Оказывается при второй итерации цикла в очередь просто не отправляются\не читаются сообщения. Интересный момент, если выполнить вторую команду (сервер повисает, не может получить это сообщение), потом аварийно "убить" сервер и заново его запустить, то автоматически срабатывает та команда которая должна была быть выполнена в прошлый раз (на которой сервер повис).
Я уже совсем не понимаю как такое возможно.


--------------------
Enjoy yourself, still you can...;)

user posted image

user posted image
PM MAIL ICQ   Вверх
svlary
Дата 17.12.2009, 06:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



У Вас запись в канал происходит вот столько раз :

Код

 for (i=1;i<=height*width;i++)
                    write(fifo,&num,sizeof(int));
   .   .  .

   А чтение  - вот столько :

Код

   for (i=1;i<wrk_count;i++)
 
        for (j=1;j<=height*wrk_def;j++)
            read(fifo,&num,sizeof(int));


   Почти на 100% уверен, что число запросов на ЧТЕНИЕ превышает число ЗАПИСЕЙ.
Вот Ваш сервер и виснет - на запросе чтения.
PM MAIL   Вверх
Anark1
Дата 17.12.2009, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 622
Регистрация: 15.12.2006
Где: RF -> Moscow

Репутация: нет
Всего: 11



svlary, 
я уже написал, что первый запрос проходит нормально и все читается как нужно. А то что вы привели, это все хорошо. Посмотрите код ниже. Поле размером height*width. Разбивается на полосы, их число wrk_count, высота у всех height, а ширина всех кроме последней wrk_def. У последней полосы ширина wrk_last (так как разбиение может быть неравномерным).

Код

void LoadFromFIFO(int * fd, int fifo, int wrk_def, int wrk_last, int wrk_count, int height)
{
    int i,j,num;
//данный цикл читает  общей сложности height*(wrk_count-1)*wrk_def

    for (i=1;i<wrk_count;i++)
    {
        for (j=1;j<=height*wrk_def;j++)
        {
            read(fifo,&num,sizeof(int));
            write(fd[2*(i-1)+1],&num,sizeof(int));
        }
    };

//данный цикл читает wrk_last*height; 
//итого в сумме с первым чтением height*((wrk_count-1)*wrk_def+wrk_last) == height*width;
    
    for (j=1;j<=height*wrk_last;j++)
    {
        read(fifo,&num,sizeof(int));
        write(fd[2*(wrk_count-1)+1],&num,sizeof(int));
    };
}


так что тут все в порядке

Это сообщение отредактировал(а) Anark1 - 17.12.2009, 10:08


--------------------
Enjoy yourself, still you can...;)

user posted image

user posted image
PM MAIL ICQ   Вверх
MAKCim
Дата 17.12.2009, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



посмотрите через strace -f, на чем зависает программа и что к этому приводит


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Anark1
Дата 17.12.2009, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 622
Регистрация: 15.12.2006
Где: RF -> Moscow

Репутация: нет
Всего: 11



Провозился, все сводится видимо к некорректности работы очереди сообщений. Эту тему наверное можно закрывать.


--------------------
Enjoy yourself, still you can...;)

user posted image

user posted image
PM MAIL ICQ   Вверх
svlary
Дата 18.12.2009, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(Anark1 @  17.12.2009,  14:07 Найти цитируемый пост)
все сводится видимо к некорректности работы очереди сообщений.

  Э... Вы намекаете, что неправильно работают ОЧЕРЕДИ ? А Ваша программа - правильная. Так ? smile

PM MAIL   Вверх
Anark1
Дата 21.12.2009, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 622
Регистрация: 15.12.2006
Где: RF -> Moscow

Репутация: нет
Всего: 11



Цитата(svlary @ 18.12.2009,  06:52)
Цитата(Anark1 @  17.12.2009,  14:07 Найти цитируемый пост)
все сводится видимо к некорректности работы очереди сообщений.

  Э... Вы намекаете, что неправильно работают ОЧЕРЕДИ ? А Ваша программа - правильная. Так ? smile

Я намекаю на то, что в cygwin IPC ресурсы реализованы не лучшим образом.
У меня не очень большой опыт написания программ под Unix, однако уверен, что мои огрехи виноваты в меньшей степени. Перепроверив код миллион раз в конечном итоге я установил виртуальную машину с FreeBSD. Под FreeBSD все работало корректно, причем код не менял.
А косяков в cygwinе было полно. Висела очередь при обмене сообщениями разных размеров, необъяснимые блокировки FIFO (не знаю при чем тут FIFO), при удалении/добавлении назад некоторых операторов взаимодействия с IPC, не влияющих на дальнейшую работу программы иногда вылетало что-то вроеде fork: child хххх - died waiting for dll loading, которое работало до этого.
Погуглил на этот счет, не у меня одного такие проблемы.
Стоило сразу ставить виртуалку, сэкномоил бы кучу времени и сил.


--------------------
Enjoy yourself, still you can...;)

user posted image

user posted image
PM MAIL ICQ   Вверх
MAKCim
Дата 21.12.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Anark1, 
винить cygwin нужно винить только в очень крайнем случае ;)
99% что ошибка у вас


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0551 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.