LINUX.ORG.RU

Виснет сервер ( язык : С, область : сокеты )


0

0

Сервер в беск цикле ждет соединений, кидает их на треды (тред выполняется 1-5 секунд), все работает как часы. Хотел добавить фичу : при запуске делаю alarm(60) и в обработчике конекчусь к другим серверам ( проверяю их состояние (дост\недоступен) ) . Некоторые доступны, некоторые заведомо недоступны. Так вот как только входим в обработчик аларма : все виснет насмерть.

Что как сделать и где копать?

Спасибо.

anonymous

>при запуске делаю alarm(60)

напрасно. сделай в отдельном треде цикл на nanosleep() && gettimeofday() и будеш иметь счастье.

>Так вот как только входим в обработчик аларма : все виснет насмерть.

по всей видимости не в том треде запускается обработчик аларма. По правильному для него надо выделить отдельный тред и привязать обработчик к этому треду который между алармами находися в состоянии близком к pause()

cvv ★★★★★
()
Ответ на: комментарий от ekto

....
set_signal ( SIGALRM, act, checkClients );
alarm(60);
...
void checkClients ( int signo, siginfo_t *info, void *par )
{
    Log << getTime() << "start checkClients...\n";
    try
    {
        std::vector<ClientInfo> cinfs;
        std::vector<Answ> rez;
        std::string strBuf;
        std::vector<ClientInfo>::iterator it = cinfs.begin();
        std::vector<ClientInfo>::iterator end = cinfs.end();
        get_list_clients ( cinfs );
        for ( ; it != end ; ++it )
        {
            try
            {
                Log << "Check for live : ip = "
                          << it->get_ip() << "\n";
              ClientSocket clientLink ( it->get_ip(), back_port );
              clientLink << "check_for_live";  clientLink >> strBuf;
              clientLink.close();
                rez.push_back ( Answ ( it->get_id(), 1, 0, 0 ) );
            }
            catch ( SocketException &serr )
            {
                rez.push_back ( Answ ( it->get_id(), 0, 0, 0 ) );
                Log << "Client is down.\n";
            }
        }
        Log << "try put_base...";
        put_base_status_client ( rez );
        Log << "ok\n";
    }
    catch ( ... )
    {
        Log << "Unknown cerr in checkClients\n";
    }
    Log << "end check Client\n\n";
    alarm ( 60 );
}


anonymous
()
Ответ на: комментарий от cvv

>по всей видимости не в том треде запускается обработчик аларма. По >правильному для него надо выделить отдельный тред и привязать >обработчик к этому треду который между алармами находися в состоянии >близком к pause()

А как можно привязать обработчик к отдельному треду? Или подразумевается обработка резеультатов аларма в отдельном треде?

anonymous
()
Ответ на: комментарий от anonymous

>Я аларм вызываю в main.

в смысле alarm()??? ну так это ничего не значит.

1)тебе сначала надо было установить обработчик аларма

2)потом создать тред в котором в бесконечном цикле будет завёрнута pause() OR nanosleep()

3)далее направить посылку всех SIGALARM в этот тред

4)и вызвать alarm()

и было бы тебе счастье. если ты изменил последовательность этих пунктов или один из них пропустил то последствия неопределены/непредсказуемы. в твоём случае имеем подвисание

PS:все пункты должны быть выполнены в одном треде или жёстко засинхронизированы например семафорами/мьютексами

cvv ★★★★★
()
Ответ на: комментарий от anonymous

>Или подразумевается обработка резеультатов аларма в отдельном треде?

ты имел ввиду создание отдельного треда в обработчике сигнала???

не думаю что хорошая идея при твоих знаниях

>А как можно привязать обработчик к отдельному треду?

читаем стивенса,маны по тредам и всё такое.

на хуж случай пользуем гугль

cvv ★★★★★
()
Ответ на: комментарий от anonymous

А ты дебажил? Не определил в каком месте "виснет"?

ekto
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.