Я пишу код на ucLinux для связи сокетов. Я использую select()
для чтения данных о сокетах. У меня также есть таймер 20 мс (созданный с использованием setitimer
), работающий в том же потоке для выполнения параллельной операции. Моя функция выбора блокируется каждый раз, когда «прерывается системным вызовом», так как он получает сигнал SIGALRM по таймеру при переполнении каждые 20 мс. Я попытался перезапустить систему, когда выпущен EINTR, и снова запустите select()
. но это не поможет, так как я всегда получаю SIGALRM таймером каждые 20 мс. Я не хочу игнорировать этот сигнал, так как он используется для выполнения других задач в системе, но я хочу использовать select без влияния этого сигнала. Есть ли способ справиться с этим? Я не могу использовать такие функции, как timer_create()
, поскольку они не поддерживаются на используемой платформе. Итак, я застрял с использованием setitimer
для создания таймера. Есть ли способ, которым я могу работать независимо друг от друга в своем коде?Запуск сокета select() и таймеров в том же потоке linux
ответ
Возможно ли вам сделать что-то подобное?
While(1) {
int rc = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
if ((rc < 0) && (errno == EINTR))
continue;
else {
// some instructions
}
}
Если это не вариант для вас, вероятно, можно использовать pselect, который добавляет параметр в конец (sigmask), который определяет набор сигналов, которые должны быть заблокированы во время pselect(), см here
Что вы делаете, это довольно странно. Посмотрим правде в глаза: таймеры - это древний и в большинстве своем устаревший механизм для работы. Практически все эти люди избегают сигналов, подобных чуме. Там нет ничего полезного в обратном вызове сигнала (вы, конечно же, не можете назвать что-то сложное, например, malloc
), поэтому у вас должен быть какой-то способ получить уведомление таймера обратно от обработчика SIGALRM
к основному потоку уже - вы На самом деле не Выполнение работы в обработчике сигналов вы?
Итак, у вас есть две тактики: используйте стандартный трюк с самоходкой, чтобы включить сигнал в событие на fd, «нормальный» способ обработки таких вещей, как SIGTERM
, SIGINT
и так далее. Вы вызываете socketpair
или pipe
, чтобы сделать трубу, а затем напишите байт в трубу от обработчика сигнала. Вы читаете байт от вас select
цикл. Вы обычно записываете значение сигнала в качестве данных, но вы можете написать что-нибудь действительно.
Другая тактика (гораздо более разумная) заключается в том, чтобы избежать беспорядка с сигналами и setitimer
полностью. setitimer
является серьезным наследием и вызывает проблемы для всех видов вещей (например, он может вызывать такие функции, как getaddrinfo
, ошибка, которая до сих пор не исправлена в glibc (http://www.cygwin.org/frysk/bugzilla/show_bug.cgi?id=15819). Сигналы плохо для вашего здоровья. «тактика - использовать аргумент таймаута для select
. У вас есть связанный список таймеров, объектов, которые вы используете для управления периодическими событиями в вашем коде. Когда вы вызываете select
, вы используете в качестве таймаута самый короткий из оставшихся таймеров. Когда select
вызов проверки, вы проверяете, истек ли какой-либо таймер, и вызовите обработчик таймера, а также обработчики для ваших fd-событий. Это стандартный цикл событий приложения. Таким образом, ваш код цикла, чтобы вы могли слушать события с таймером, а также fd -driven. Практически каждое приложение в вашей системе использует какой-то вариант этого механизма.
- 1. Запуск таймеров в Java
- 2. Запуск как AQXMLParser, так и NSXMLParser в том же приложении
- 3. Запуск двух таймеров одновременно
- 4. Запуск нескольких таймеров?
- 5. Как вызвать system.threading.timer в том же потоке?
- 6. Запуск MariaDB & MySQL на том же сервере
- 7. Чтение и запись в файл в том же потоке
- 8. fread и fgetc в том же потоке файлов не работают
- 9. Запуск многих таймеров одновременно в AS3
- 10. Подсистемы таймеров Linux: точность и разрешение
- 11. Eloquent multiple select в том же запросе
- 12. Запуск многоуровневых макросов в том же листе
- 13. Какова точность интервальных таймеров в Linux?
- 14. Запуск обоих python 2.6 и 3.1 на том же компьютере
- 15. MYSQL SELECT и INCREMENT в том же вопросе?
- 16. Команда SELECT и INSERT в том же заявлении sql
- 17. php UPDATE и SELECT в том же запросе
- 18. SQL COUNT в одном и том же запросе select
- 19. Запуск службы и активности в том же экземпляре
- 20. Запуск стандартной и гибкой среды в том же облачном интерфейсе
- 21. Запуск сервера и клиента в том же файле - python
- 22. Ошибка чтения элемента дважды в том же соединении сокета unix
- 23. Запуск NSTimer в потоке
- 24. Запуск SimpleXMLRPCServer в отдельном потоке и завершение
- 25. Обработка данных сокета Linux c
- 26. Чтение обновленного CSV в том же потоке в Jmeter
- 27. Почему не удается вызвать 'select' рекурсивно для неблокирующего сокета Linux
- 28. Отправить несколько сообщений HL7 в том же соединении сокета
- 29. Запуск GameWindow в потоке
- 30. Запуск кода в потоке
Привет, Спасибо за ваше предложение. Я уже это сделал. но проблема заключается в том, что он продолжает циклически переключаться в select, так как он продолжает получать EINTR системой через каждые 20 мс, что является периодом таймера, запущенного в том же потоке. Итак, у меня есть функция выбора, которая продолжает работать, получая прерывается и работает снова, и в конечном итоге заканчивается ничего не читает в сокетах, просто продолжает цикл, выдавая прерывистый сигнал вызова. Любой способ избежать этого? Мне нужен таймер в том же потоке, я не могу игнорировать сигнал таймера, и я не могу заблокировать функцию выбора. Любой способ достижения обоих? – user2069669
@ user2069669 добавлена ссылка на pselect, вы можете использовать вместо select – Jekyll