C: прервать выполнение функции через n секунд (безопасно)
Модератор: Модераторы разделов
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
C: прервать выполнение функции через n секунд
Всем привет.
Искал ответ, но нашел решение только для отдельных процессов, выполнение которые можно оборвать при помощи сигнала. Мне же надо сделать тоже самое, но с обычной функцией.
Проходит n cекунд, и если функция все еще работает, то происходит автоматическое принудительное возвращение в вызывающую (например main) функцию. Я не уверен, что это вообще можно сделать...
Если кто сталкивался с такой задачей и знает как именно это можно реализовать, буду благодарен за любую информацию.
Искал ответ, но нашел решение только для отдельных процессов, выполнение которые можно оборвать при помощи сигнала. Мне же надо сделать тоже самое, но с обычной функцией.
Проходит n cекунд, и если функция все еще работает, то происходит автоматическое принудительное возвращение в вызывающую (например main) функцию. Я не уверен, что это вообще можно сделать...
Если кто сталкивался с такой задачей и знает как именно это можно реализовать, буду благодарен за любую информацию.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Сообщения: 501
- ОС: Debian Wheezy / Gentoo
Re: C: прервать выполнение функции через n секунд
Как я слышал, обходятся ассемблерными вставками, но не гарантирую верность информации.
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Тут, как я понимаю, нужен во-первых таймер. Само собой.
И во-вторых, все же как-то надо распараллелить процесс.
И во-вторых, все же как-то надо распараллелить процесс.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: прервать выполнение функции через n секунд
Какое доверие к прерываемому процессу? Первая простая схема: поток 1 запускает поток 2, ждёт n секунд, после чего устанавливает флаг и join к потоку 2; поток 2 выполняет работу, периодически проверяя флаг, если всё норм, то выходит раньше времени.
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Не процесс, а функция. Процесс прихлопнуть с помощью сигнала не проблема. Как реализовать "подобные отношения" в пределах одного потока/процесса?
Поток или просто при помощи fork() это понятно. А как это сделать с обычной функцией? Что-то самое простое: main() вызывает f(), f() (в любом случае!) вызывает return через n секунд (либо сама main каким-то образом завершает f()).
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Модератор
- Сообщения: 21119
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: C: прервать выполнение функции через n секунд
Аргументом передавать ей таймаут, внутри в цикле проверять, не прошёл ли он. Разве это не очевидно?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
Спасибо сказали:
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Bizdelnick писал(а): ↑20.11.2014 19:35
Аргументом передавать ей таймаут, внутри в цикле проверять, не прошёл ли он. Разве это не очевидно?
Вызываемая функция в свою очередь вызвает, к примеру, socket(), ответ от которого можно ждать... достаточно долго. Мне не нужен результат socket(), если ответ я жду более n секунд.
Куда Вы хотите поместить цикл, мне... да, не очевидно.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Модератор
- Сообщения: 21119
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: C: прервать выполнение функции через n секунд
socket() работает долго? С чего бы?
Вы, может быть, что-то вроде этого имеете в виду: https://stackoverflow.com/questions/4181784...ple-connections ?
Вы, может быть, что-то вроде этого имеете в виду: https://stackoverflow.com/questions/4181784...ple-connections ?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: прервать выполнение функции через n секунд
Я думал, что проблема в том, что сигналы работают на процесс, а не поток. Тогда да, как сказал Bizdelnick — просто параметр и проверка не достигнут ли таймаут. Вопрос доверия к коду функции остаётся, не должно быть блокирующих функций.
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
В идеале их конечно же не должно быть, но при работе с сетью всякое, знаете ли, случается. Характер ответов от каких-нибудь ESX постоянно меняется от версии к версии.
Я написал "к примеру". Это может быть любая функция. Вам нужен пример функции, которая всегда запинается и подвешивает весь процесс?
Я хочу узнать как именно прервать функцию. У меня нет возможности после каждой операции в вызываемой функции проверять переданное значение таймаута, сравнивать его и, если оно именно то, что нужно, вызвать return.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Модератор
- Сообщения: 21119
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: C: прервать выполнение функции через n секунд
Stauffenberg писал(а): ↑21.11.2014 00:36Я написал "к примеру". Это может быть любая функция. Вам нужен пример функции, которая всегда запинается и подвешивает весь процесс?
Не надо примеров. Давайте конкретную функцию, с которой возникла проблема. Для всего, что работает с сетью, должен быть предусмотрен таймаут, если Вы его не нашли, - значит плохо искали (ну или используете какую-то совсем уж непотребную библиотеку). Попробуем поискать вместе.
"Прервать функцию" извне нельзя. Ну сами подумайте, если у Вас всего один поток, то кто эту функцию будет прерывать?
Stauffenberg писал(а): ↑21.11.2014 00:36У меня нет возможности после каждой операции в вызываемой функции проверять переданное значение таймаута, сравнивать его и, если оно именно то, что нужно, вызвать return.
Возможность у Вас есть. Вероятно, нет желания. И, скорее всего, правильно, что нет.
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Bizdelnick писал(а): ↑21.11.2014 01:01
"Прервать функцию" извне нельзя. Ну сами подумайте, если у Вас всего один поток, то кто эту функцию будет прерывать?
Ну так поэтому я и написал:
Тут, как я понимаю, нужен во-первых таймер. Само собой.
И во-вторых, все же как-то надо распараллелить процесс.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Bizdelnick писал(а): ↑21.11.2014 01:01Stauffenberg писал(а): ↑21.11.2014 00:36Я написал "к примеру". Это может быть любая функция. Вам нужен пример функции, которая всегда запинается и подвешивает весь процесс?
Не надо примеров. Давайте конкретную функцию, с которой возникла проблема. Для всего, что работает с сетью, должен быть предусмотрен таймаут, если Вы его не нашли, - значит плохо искали (ну или используете какую-то совсем уж непотребную библиотеку). Попробуем поискать вместе.
Спасибо конечно, поискать я и сам могу. Тратить чужое время ни к чему.
Как всегда и бывает, сложность проблемы в том, что накладываются несколько условий, и очень тяжело описать ВСЮ ситуацию целиком. Пытаешься разбить ее на части и спросить о том, что кажется наиболее вероятной причиной из тех, которые не понимаешь.
В моем конкретном случае я имею несколько параллеьных процессов, которые создают несколько разных соединений. Тут и icmp (raw-сокет), и я опрашиваю snmp (161/UDP), и еще создается несколько TCP-запросов, например, nsclient (12489/TCP). Все это работает вместе, и в данном случае очень сложно все это разбить на отдельные функции, потому что походу сканирования производится анализ для принятия решения о дальнейших действий и используются общие структуры для разных типов соединений.
Например, nsclient работает только на Windows, следовательно запрос на него надо делать только после того, как получили ответ от SNMP об используемой ОС, а SNMP конечно же UDP, так что мы должны использовать задержку... и мы вообще не можем узнать сразу получим ли мы ответ от SNMP или нет. Программа должна работать как можно быстрее, но еще важнее - чтобы ни в коем случае "опоздавший" ответ не был потерян и, как следствие, проигнорирован. Некоторые Cisco-рутеры, фаерволы, ESX, или какие-то другие сетевые устройства с гибридными функциями... запросы вообще фильтруют (не отбрасывают, когда ты можешь это увидеть, а фильтруют, так, что ты понятия не имеешь, что случилось с твоим пакетом. Это устройство включено? Оно есть в сети? Оно просто так настроено, что не отвечает?). И это еще не все... Это просто логика программы. Тут накладывается еще несколько проблем, связанных с окружением, в котором все это будет работать, которые тоже стоит учитывать и следоательно - тут описывать.
Обо всем этом нет смысла тут спрашивать, да и учился я не для того, чтобы проблемы с помощью форума решать. Я разбиваю задачу на подзадачи, проблему на подпроблемы. Что-то могу отбросить сразу, что-то запрограммировать иначе, что-то найти в интернете, что-то - спросить на этом форуме, а что-то - в специальной рассылке по сетям. Но в этом случае вопрос получается очень абстрактный, потому что это лишь десятая часть проблемы, на которую со всех сторон давят те или иные условия. Дебажа эту проблему, мне легче всего "отрезать" то, что сразу понятно, что сломано. Тут и так процесс на процессе, поток на потоке, поэтому еще глубже уходить в это слишком муторно. Мне просто пришла в голову идея гасить функции, если что-то в ней пошло не так. Я никогда этого не делал. Как только остальная часть программы будет работать как надо, я вернусь и перепрограммирую проблемные участки кода.
Так о чем это я? Да, я просто хотел сказать, что в проблеме разберусь сам, а вот узнать как возвращаться из "зомби-функции" принудительно, было бы прикольно

Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Модератор
- Сообщения: 21119
- Статус: nulla salus bello
- ОС: Debian GNU/Linux
Re: C: прервать выполнение функции через n секунд
В сторону использования неблокирующего режима не смотрели?
Пишите правильно:
в консоли вку́пе (с чем-либо) в общем вообще | в течение (часа) новичок нюанс по умолчанию | приемлемо проблема пробовать трафик |
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: прервать выполнение функции через n секунд
Stauffenberg писал(а): ↑20.11.2014 15:54Искал ответ, но нашел решение только для отдельных процессов, выполнение которые можно оборвать при помощи сигнала. Мне же надо сделать тоже самое, но с обычной функцией.
NoWay
делить на ноль нельзя. Вам обязательно нужен другой процесс, для отслеживания вашей функции.
Bizdelnick писал(а): ↑20.11.2014 19:35Аргументом передавать ей таймаут, внутри в цикле проверять, не прошёл ли он. Разве это не очевидно?
это не прерывание. Это просто функция, которая помимо всего прочего считает время, и завершается, если время вышло.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: прервать выполнение функции через n секунд
Stauffenberg
Учтите, нельзя прервать что-то "хорошо". Такое "хорошее" прерывание можно сделать внитри самого кода: проверкой функции, setjmp/longjmp, исключения. Но извне (процесс или поток — не важно) всегда можно попасть в плохое место, это нормально для Вас?
Учтите, нельзя прервать что-то "хорошо". Такое "хорошее" прерывание можно сделать внитри самого кода: проверкой функции, setjmp/longjmp, исключения. Но извне (процесс или поток — не важно) всегда можно попасть в плохое место, это нормально для Вас?
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
Ладно, всем спасибо. Буду дальше разбираться.
Еще раз спасибо за ответы.
Вот именно поэтому в описании к теме написано "безопасно" (:
Но сейчас меня интересует возможность прерывания в принципе.
Естественно с этого все начиналось
Еще раз спасибо за ответы.
NickLion писал(а): ↑21.11.2014 10:42Stauffenberg
Учтите, нельзя прервать что-то "хорошо". Такое "хорошее" прерывание можно сделать внитри самого кода: проверкой функции, setjmp/longjmp, исключения. Но извне (процесс или поток — не важно) всегда можно попасть в плохое место, это нормально для Вас?
Вот именно поэтому в описании к теме написано "безопасно" (:
Но сейчас меня интересует возможность прерывания в принципе.
Естественно с этого все начиналось
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: прервать выполнение функции через n секунд
Прервать в принципе — pthread_cancel, pthread_kill.
-
- Сообщения: 2041
- Статус: ☮ PEACE ☮
- ОС: открытая и свободная
Re: C: прервать выполнение функции через n секунд
К примеру, connect() легко прерывается после n секунд вот так:
Код: Выделить всё
void alarm_hndlr (int sig)
{
return;
}
int main()
{
...
signal(SIGALRM, alarm_hndlr);
alarm(5);
rc = connect (s, (struct sockaddr *)&peer, sizeof(peer));
alarm(0);
if (rc < 0)
{
if (error == EINTR)
error(1, 0, "halli hallo\n");
...
}
Есть еще select(), исключающих блокировку, но накладывающий ряд своих проблем.
Labor omnia vincit
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.” (Brian Kernighan)
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: прервать выполнение функции через n секунд
оно там внутри где-то форкается. Для этой функции прерывание — штатная фича.
Есть и код ошибки для этого случая:
Код: Выделить всё
EINTR The system call was interrupted by a signal that was caught; see signal(7).