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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: синхронизировать потоки и libpcap  (Прочитано 7421 раз)
verona
Гость
« : Январь 10, 2013, 10:23 »

привет всем.

правильно ли я синхронизирую потоки? мне нужно, чтобы потоки thread1 и thread2 выполнялись строго поочередно:
код главного gui потока:
Код:
class MainWidget : public QWidget
{
    Q_OBJECT
    
public:
    thread1 *t1;
    thread2 *t2;
    view_iko *view1;
    QMutex mutex;
public slots:
    void startWorking(){
        t1->start();
        t2->start();
        isrunning=true;
    }
поток thread1:
Код:
#include <QThread>
#include "pcap.h"
class thread1 : public QThread
{
    Q_OBJECT
public:
    explicit thread1(QObject *parent = 0);
    ~thread1();
    pcap_t *handle;
private:
    int gotpacket();
protected:
    void run();
};
Код:
void thread1::run()
{
    bool ch;
    while(1){
        mw->mutex.lock(); // mw - это указатель на класс MainWidget
        ch=true;
        while(ch){
        Data = pcap_next(handle,&header);
        if (Data !=0)
        if(gotpacket()==111)ch=false;

        }
        mw->mutex.unlock();
    }
}
код thread2:
Код:
#include <QThread>
#include <QtCore>
class thread2 : public QThread
{
    Q_OBJECT
public:
    thread2();
protected:
    void run();
private:
    void func1();
    void func2();
    void func3();
    void func4();
    void func5();
    void func6();
    void func7();
    void func8();
signals:
    void ready();
};
Код:
void thread2::run()
{
     int count;
    while(1)
    {
            mw->mutex.lock();
            func1();
            func2();
            func3();
            func4();
            func5();
            func6();
            func7();
            count++;
           mw->mutex.unlock();
    }
}

при работе программа выдает ошибку сегментации.
правильно ли я делаю синхронизацию? .
дело в том, что поток thread1 используется для приема пакетов по сети с помощью libpcap, и возможно из-за нее вылазит ошибка.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

правильно ли я делаю синхронизацию? .
Вы ее не делаете Улыбающийся Да, Вы защитили участки кода мутексом, но нет гарантий что обработчик (thread2) захватит мутекс и начнет делать func1(2, 3) уже после того как данные считаны. Можно использовать семафоры
Код
C++ (Qt)
QSemaphore theSemaphore1(1), theSemaphore2(0);
 
void thread1::run()
{
   bool ch;
   while(1) {
       theSemaphore1.acquire();   // ждем конца обработки
       ch=true;
       while(ch){
        Data = pcap_next(handle,&header);
        if (Data !=0)
        if(gotpacket()==111)ch=false;
       }
       theSemaphore2.release();  // открываем семафор thread2
   }
}
 
void thread2::run()
{
    int count;
   while(1)
   {
           theSemaphore2.acquire();   // ждем конца чтения
           func1();
           func2();
           func3();
           func4();
           func5();
           func6();
           func7();
           count++;
          theSemaphore1.release();  // открываем семафор thread1
    }
}
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

правильно ли я делаю синхронизацию? .
Нет.
В таких задачах взаимодействует поток-производитель, поток-потребитель и данные, которые и нужно защищать.
Если хочешь разобраться, то сделай просто тестовую программку, без pcap, и на ней уже пробуй.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Можно использовать семафоры
для получения бесполезной многозадачности? Улыбающийся

Пока одна нитка выполняется, другая всегда стоит, а ядро тратим время на переключение контекстов.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

для получения бесполезной многозадачности? Улыбающийся

Пока одна нитка выполняется, другая всегда стоит, а ядро тратим время на переключение контекстов.
Да, но таково условие задачи
мне нужно, чтобы потоки thread1 и thread2 выполнялись строго поочередно:
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Да, но таково условие задачи
Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. Улыбающийся
Это утверждение слишком категорично. Напр если обработчиков 2 или более - все вполне разумно
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Это утверждение слишком категорично.
Разве?

Напр если обработчиков 2 или более - все вполне разумно
Как это может соотноситься с
Цитировать
мне нужно, чтобы потоки thread1 и thread2 выполнялись строго поочередно:
Улыбающийся

Хорошо, пусть будет 2 (или более) потока, которые должны выполняться строго один за другим и при выполнении одного, другой (другие) должны стоять и ждать.
В чем смысл этого разделения, если все равно код выполняется последовательно и лучше всего будет выполняться в одном потоке, т.к. там не будет побочных потерь на переключение контекста потоков. Улыбающийся
« Последнее редактирование: Январь 10, 2013, 11:44 от Old » Записан
verona
Гость
« Ответ #8 : Январь 10, 2013, 13:54 »

правильно ли я делаю синхронизацию? .
Вы ее не делаете Улыбающийся Да, Вы защитили участки кода мутексом, но нет гарантий что обработчик (thread2) захватит мутекс и начнет делать func1(2, 3) уже после того как данные считаны. Можно использовать семафоры
Код
C++ (Qt)
QSemaphore theSemaphore1(1), theSemaphore2(0);
 
void thread1::run()
{
   bool ch;
   while(1) {
       theSemaphore1.acquire();   // ждем конца обработки
       ch=true;
       while(ch){
        Data = pcap_next(handle,&header);
        if (Data !=0)
        if(gotpacket()==111)ch=false;
       }
       theSemaphore2.release();  // открываем семафор thread2
   }
}
 
void thread2::run()
{
    int count;
   while(1)
   {
           theSemaphore2.acquire();   // ждем конца чтения
           func1();
           func2();
           func3();
           func4();
           func5();
           func6();
           func7();
           count++;
          theSemaphore1.release();  // открываем семафор thread1
    }
}
 

сделал как показали через семафоры, единственное объявил их как public члены mainwidget, соот-во доступ к ним из потоков происходит вот так: mw->semaphore1...
я уже отключил все другие модули программы, сейчас только обозначенные потоки работают без всяких лишних операций  и ... по прежнему не работает.
Записан
verona
Гость
« Ответ #9 : Январь 10, 2013, 13:56 »

Да, но таково условие задачи
Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. Улыбающийся

в будущем предполагается сделать circular buffer
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

в будущем предполагается сделать circular buffer
В каком будущем? Улыбающийся
То что ты пытаешься сделать - это вообще не решение. Ты однопоточное решение хочешь разбить на несколько потоков, так не получиться, оно по прежнему будет однопоточное.
Нужна очередь, куда поток слушающий pcap будет складывать данные, а один или несколько потоков-обработчиков будут эти данные из очереди брать и обрабатывать.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

Я ему уже посоветовал в другом его топике вообще отказаться от потоков, или использовать один отдельный поток для перехвата траффика через PCAP.
Тогда лучше всего работать с PCAP в неблокирующем режиме через QSocketNotifier и использовать сигналы/слоты,
я ему даже дал ссылку на Qt wrapper для PCAP (для Linux).

Но ТС упорно продолжает гнуть свою линию с какой-то хренотенью в которой не разбирается и все усложняет.  В замешательстве

Мда...
Записан

ArchLinux x86_64 / Win10 64 bit
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Но ТС упорно продолжает гнуть свою линию с какой-то хренотенью в которой не разбирается и все усложняет.  В замешательстве
Вполне возможно (и даже очень вероятно) что предложенное Вами решение по-любому лучше. Но все же не стоит его навязывать. В этой теме человек спросил конкретный вопрос - ну и дадим конкретный ответ. А "зачем так делать" - то его проблемы, вот спросит как лучше, тогда и ответим  Улыбающийся

сделал как показали через семафоры, единственное объявил их как public члены mainwidget, соот-во доступ к ним из потоков происходит вот так: mw->semaphore1...
я уже отключил все другие модули программы, сейчас только обозначенные потоки работают без всяких лишних операций  и ... по прежнему не работает.
Впечатление что Вы как-то легкомысленно относитесь к архитектуре своего приложения. Быстренько попробовать - ага, не получилось, значит другое попробовать и.т.д. Разбираться надо где, что и как не работает.
Записан
verona
Гость
« Ответ #13 : Январь 18, 2013, 13:59 »

Я ему уже посоветовал в другом его топике вообще отказаться от потоков, или использовать один отдельный поток для перехвата траффика через PCAP.
Тогда лучше всего работать с PCAP в неблокирующем режиме через QSocketNotifier и использовать сигналы/слоты,
я ему даже дал ссылку на Qt wrapper для PCAP (для Linux).

Но ТС упорно продолжает гнуть свою линию с какой-то хренотенью в которой не разбирается и все усложняет.  В замешательстве

Мда...

а как решить проблему с высокой загрузкой CPU ?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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