Russian Qt Forum
Октябрь 04, 2024, 12:31 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: libpcap и поток  (Прочитано 6980 раз)
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
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Январь 10, 2013, 09:40 »

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

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

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

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Январь 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 - то немного по-другому надо использовать...
Записан

ArchLinux x86_64 / Win10 64 bit
Dancing_on_water
Гость
« Ответ #3 : Январь 10, 2013, 11:19 »

Похоже вызывать методы gui напрямую из другого поотока это хит последнего времени.

Не вызываейте методы из другого потока, используйте сигналы слоты с соединением через очередь
Записан
verona
Гость
« Ответ #4 : Январь 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-поток у меня рисует, один для обработки, и еще один для приема данных
Записан
verona
Гость
« Ответ #5 : Январь 10, 2013, 14:04 »

Похоже вызывать методы gui напрямую из другого поотока это хит последнего времени.

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

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Январь 10, 2013, 14:30 »

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

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

ArchLinux x86_64 / Win10 64 bit
Dancing_on_water
Гость
« Ответ #7 : Январь 10, 2013, 17:20 »

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

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

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

Сообщений: 606



Просмотр профиля
« Ответ #8 : Январь 10, 2013, 17:50 »


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

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

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Январь 10, 2013, 18:00 »

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

Ну строго говоря да. Под потокобезопасностью я имел ввиду второй пункт ).
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.135 секунд. Запросов: 22.