URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9367
[ Назад ]

Исходное сообщение
"Принудительный выход из блокирующей функции"

Отправлено goodfornothing , 28-Янв-12 18:09 
Здравствуйте!

Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных, приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap. В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета. Например, поток висит в функции и в это время пользователь решает изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо, чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную задачу?

Спасибо!


Содержание

Сообщения в этом обсуждении
"Принудительный выход из блокирующей функции"
Отправлено dima , 29-Янв-12 04:31 
> Здравствуйте!
> Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных,
> приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap.
> В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо
> обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета.
> Например, поток висит в функции и в это время пользователь решает
> изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо,
> чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную
> задачу?
> Спасибо!

давно уже есть Ethereal



"Принудительный выход из блокирующей функции"
Отправлено goodfornothing , 04-Фев-12 13:16 
>[оверквотинг удален]
>> Пишу приложение с использованием Qt. Имеется поток назначение которого, - захват данных,
>> приходящих на сетевой интерфейс компьютера. Для захвата используется библиотека Libpcap.
>> В потоке вызывается блокирующая функция захвата пакетов, например, pcap_loop. Необходимо
>> обеспечить возможность выхода из данной функции, не дожидаясь события захвата пакета.
>> Например, поток висит в функции и в это время пользователь решает
>> изменить выражение фильтра. Чтобы заново скомпилировать выражение фильтра, необходимо,
>> чтобы блокирующая функция вернула управление потоку. Каким образом можно решить данную
>> задачу?
>> Спасибо!
> давно уже есть Ethereal

А подробнее можно?


"Принудительный выход из блокирующей функции"
Отправлено fork , 05-Фев-12 01:05 
Предлагается использовать Etheral вместо Libpcap, насколько я понял. Не знаком ни с  Libpcap ни с Etheral, но думаю можно добавить таймаут в ту блокирующую функцию, чтобы периодически её запускать во время работы, но и обрабатывать различные ситуации вроде той, когда пользователь решит изменить выражение фильтра. Либо добавить(использовать) управление заданием той самой функции из другого потока.



"Принудительный выход из блокирующей функции"
Отправлено goodfornothing , 05-Фев-12 14:58 
>  Предлагается использовать Etheral вместо Libpcap, насколько я понял. Не знаком ни
> с  Libpcap ни с Etheral, но думаю можно добавить таймаут
> в ту блокирующую функцию, чтобы периодически её запускать во время работы,
> но и обрабатывать различные ситуации вроде той, когда пользователь решит изменить
> выражение фильтра. Либо добавить(использовать) управление заданием той самой функции
> из другого потока.

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


"Принудительный выход из блокирующей функции"
Отправлено fork , 05-Фев-12 22:12 
> принудительно завершать поток, в котором вызвана функция и перезапускать его

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


"Принудительный выход из блокирующей функции"
Отправлено fork , 05-Фев-12 22:25 
>принудительно завершать поток, в котором вызвана функция и перезапускать его

Вы знаете на каком месте поток остановится и какие ресурсы он может занять, но не успеть освободить и кроме того вы готовы постоянно плодить новые потоки? Почитайте документацию, например эту http://www.tcpdump.org/pcap.html  ,либо дождитесь завершения потока.

int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

Второй аргумент
Following that is an integer that tells pcap_loop() how many packets it should sniff for before returning (a negative value means it should sniff until an error occurs).

Устанавливайте количество, переменную cnt, после чего запускайте обработчик ввода пользователя и снова pcap_loop. И никаких блокировок не будет



"Принудительный выход из блокирующей функции"
Отправлено goodfornothing , 07-Фев-12 22:23 
> int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
> Второй аргумент
> Following that is an integer that tells pcap_loop() how many packets it
> should sniff for before returning (a negative value means it should
> sniff until an error occurs).
> Устанавливайте количество, переменную cnt, после чего запускайте обработчик ввода пользователя
> и снова pcap_loop. И никаких блокировок не будет

Даже если я вызову pcap_loop со значением cnt равным "1", поток будет висеть в этой функции до скончания века, если данный пакет не будет принят по каким-то причинам. Как Вы предлагаете в данном случае выйти из pcap_loop?

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


"Принудительный выход из блокирующей функции"
Отправлено fork , 08-Фев-12 02:07 
Да, я предполагал, что, возможно, это приведет к потере пакетов, скорость может быть огромная. Вы проверяли это? В любом случае в библиотеке должны быть механизмы, решающие эту проблему без потери пакетов, хотя, может быть, и на более мощном железе. Как бы логично, что опрос тех пакетов никак не может помешать проверить в этой же функции один единственный флаг о необходимости завершить этот опрос, в том же коллбэке больше операций выполняется.