Russian Qt Forum

Qt => Работа с сетью => Тема начата: verona от Январь 10, 2013, 08:55



Название: libpcap и поток
Отправлено: verona от Январь 10, 2013, 08:55
здравствуйте! подскажите пожалуйста:
в «проблемном» потоке-наследнике qthread выполняется следующий цикл:
Код:
while(stop)
{
   data=pcap_next(pcap_next(handle,&header);
   if(gotpacket()==1){  // gotpacket()- это фильтр для pcap
          func1();
          ...
          func8();  // функции обработки принятых данных
     }
}

в теле выполнения функций func1,..,func8 происходит обращение к public членам gui-потока и еще одного qthread-потока. когда это происходит вылетает ошибка сегментации.

инициализация библиотеки pcap:
Код:
char *dev, errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr header;
const u_char *Data;
dev = pcap_lookupdev(errbuf);
    if (dev == NULL) {
                    fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
                    //return(2);
                }
    printf("Device: %s\n", dev);
    handle = pcap_open_live(dev, BUFSIZ, 1, -1, errbuf);
    if(handle == NULL){
            fprintf(stderr, "Error: %s\n", errbuf);

        }


если же я получаю данные без libpcapa, к примеру считываю сохраненные данные с диска, то подобных ошибок не возникает. такое ощущение, что pcap блокирует поток или процесс.

похожие проблемы возникают если «проблемный» поток заменить на два потока: читатель и писатель. их синхронизирую стандартыными средствами QWaitCondition или QSemaphore, в соответсвии с примерами в документации, и объявляются они в gui-потоке(доступ к ним через указатель). В этом случае возникают глюки: код защищенный средствами синхронизации может выполняться, даже несмотря на то, что соответвующие мьютексы и т.п. уже заняты в другом потоке.
p.s. ОС linux


Название: Re: libpcap и поток
Отправлено: Old от Январь 10, 2013, 09:40
в теле выполнения функций func1,..,func8 происходит обращение к public членам gui-потока и еще одного qthread-потока. когда это происходит вылетает ошибка сегментации.
Эти "обращения" и нужно показывать в первую очередь. ;)

если же я получаю данные без libpcapa, к примеру считываю сохраненные данные с диска, то подобных ошибок не возникает. такое ощущение, что pcap блокирует поток или процесс.
Конечно блокирует, до поступления очередной порции данных.

похожие проблемы возникают если «проблемный» поток заменить на два потока: читатель и писатель. их синхронизирую стандартыными средствами QWaitCondition или QSemaphore, в соответсвии с примерами в документации, и объявляются они в gui-потоке(доступ к ним через указатель). В этом случае возникают глюки: код защищенный средствами синхронизации может выполняться, даже несмотря на то, что соответвующие мьютексы и т.п. уже заняты в другом потоке.
При правильном использовании такого не может быть.


Название: Re: libpcap и поток
Отправлено: kuzulis от Январь 10, 2013, 10:50
ТС, лучше не используй потоки, а работай с PCAP в асинхронном режиме (Event-based mode).
См. в сторону pcap_get_selectable_fd и QSocketNotifier, это что касается Linux-овой реализации PCAP.

Посмотри также на уже готовый Qt-шный враппер: http://blogs.kde.org/2011/03/19/qpcap-qt-style-wrapper-around-libpcap

Если же тебе нужен и WinPCAP - то немного по-другому надо использовать...


Название: Re: libpcap и поток
Отправлено: Dancing_on_water от Январь 10, 2013, 11:19
Похоже вызывать методы gui напрямую из другого поотока это хит последнего времени.

Не вызываейте методы из другого потока, используйте сигналы слоты с соединением через очередь


Название: Re: libpcap и поток
Отправлено: verona от Январь 10, 2013, 13:58
ТС, лучше не используй потоки, а работай с PCAP в асинхронном режиме (Event-based mode).
См. в сторону pcap_get_selectable_fd и QSocketNotifier, это что касается Linux-овой реализации PCAP.

Посмотри также на уже готовый Qt-шный враппер: http://blogs.kde.org/2011/03/19/qpcap-qt-style-wrapper-around-libpcap

Если же тебе нужен и WinPCAP - то немного по-другому надо использовать...
почему лучше не использовать потоки? у меня задача такая: нужно принять данные по сети, обработать их и визуализировать. соот-во gui-поток у меня рисует, один для обработки, и еще один для приема данных


Название: Re: libpcap и поток
Отправлено: verona от Январь 10, 2013, 14:04
Похоже вызывать методы gui напрямую из другого поотока это хит последнего времени.

Не вызываейте методы из другого потока, используйте сигналы слоты с соединением через очередь
а если у меня допустим матрица в которую пишут и из которой читают, плюс пара десятков переменных и разных контейнеров. и доступ к ним нужен как gui-потоку, т.к. ещу двум qthread-потокам. тогда при передаче через сигналы могу передавать через указатели, т.к. хочется избежать копирования большого кол-ва данных. 
существует ли в такой ситуации альтернативный способ где-нибудь объявить глобальные данные?
сейчас они объявляются в public членах виджета и qthreads


Название: Re: libpcap и поток
Отправлено: kuzulis от Январь 10, 2013, 14:30
почему лучше не использовать потоки? у меня задача такая: нужно принять данные по сети, обработать их и визуализировать. соот-во gui-поток у меня рисует, один для обработки, и еще один для приема данных

Потому что они избыточны в этой задаче.
На крайняк - используй один отдельный поток для приема данных, в котором используй Qt-шный враппер PCAP, на который я дал тебе ссылку,
в евент-базед моде.


Название: Re: libpcap и поток
Отправлено: Dancing_on_water от Январь 10, 2013, 17:20
а если у меня допустим матрица в которую пишут и из которой читают, плюс пара десятков переменных и разных контейнеров. и доступ к ним нужен как gui-потоку, т.к. ещу двум qthread-потокам. тогда при передаче через сигналы могу передавать через указатели, т.к. хочется избежать копирования большого кол-ва данных. 
существует ли в такой ситуации альтернативный способ где-нибудь объявить глобальные данные?
сейчас они объявляются в public членах виджета и qthreads

В контейнерах Qt хранение - shared. Копирование объекта фактически равно копированию указателя. + с помощью счетчика ссылок организована потокобезопасность.

Для других данных да - перекидывать через указатели, ну либо что-то на подобии Qt-овских контейнеров


Название: Re: libpcap и поток
Отправлено: alex312 от Январь 10, 2013, 17:50

В контейнерах Qt хранение - shared. Копирование объекта фактически равно копированию указателя. + с помощью счетчика ссылок организована потокобезопасность.

1. Контейнеры Qt потокоНЕбезопасны, они реентерабельны. ( http://qt-project.org/doc/qt-4.8/threads-reentrancy.html )
2. Копирование, конечно быстрое, но надо помнить что при модификации одного из контейнеров, которые ссылаются на общие данные всеравно произойдет полное копирование.


Название: Re: libpcap и поток
Отправлено: Igors от Январь 10, 2013, 18:00
а если у меня допустим матрица в которую пишут и из которой читают, плюс пара десятков переменных и разных контейнеров. и доступ к ним нужен как gui-потоку, т.к. ещу двум qthread-потокам. тогда при передаче через сигналы могу передавать через указатели, т.к. хочется избежать копирования большого кол-ва данных. 
существует ли в такой ситуации альтернативный способ где-нибудь объявить глобальные данные?
сейчас они объявляются в public членах виджета и qthreads
Неясно зачем Вам объявлять как-то еще. Если нужно защитить по чтению/хаписи, то стандартное решение QReadWriteLock


Название: Re: libpcap и поток
Отправлено: Dancing_on_water от Январь 10, 2013, 18:12
Ну строго говоря да. Под потокобезопасностью я имел ввиду второй пункт ).