Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: verona от Январь 10, 2013, 10:23



Название: синхронизировать потоки и libpcap
Отправлено: 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, и возможно из-за нее вылазит ошибка.


Название: Re: синхронизировать потоки и libpcap
Отправлено: Igors от Январь 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
    }
}
 


Название: Re: синхронизировать потоки и libpcap
Отправлено: Old от Январь 10, 2013, 11:00
правильно ли я делаю синхронизацию? .
Нет.
В таких задачах взаимодействует поток-производитель, поток-потребитель и данные, которые и нужно защищать.
Если хочешь разобраться, то сделай просто тестовую программку, без pcap, и на ней уже пробуй.


Название: Re: синхронизировать потоки и libpcap
Отправлено: Old от Январь 10, 2013, 11:06
Можно использовать семафоры
для получения бесполезной многозадачности? :)

Пока одна нитка выполняется, другая всегда стоит, а ядро тратим время на переключение контекстов.


Название: Re: синхронизировать потоки и libpcap
Отправлено: Igors от Январь 10, 2013, 11:11
для получения бесполезной многозадачности? :)

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


Название: Re: синхронизировать потоки и libpcap
Отправлено: Old от Январь 10, 2013, 11:17
Да, но таково условие задачи
Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. :)


Название: Re: синхронизировать потоки и libpcap
Отправлено: Igors от Январь 10, 2013, 11:28
Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. :)
Это утверждение слишком категорично. Напр если обработчиков 2 или более - все вполне разумно


Название: Re: синхронизировать потоки и libpcap
Отправлено: Old от Январь 10, 2013, 11:31
Это утверждение слишком категорично.
Разве?

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

Хорошо, пусть будет 2 (или более) потока, которые должны выполняться строго один за другим и при выполнении одного, другой (другие) должны стоять и ждать.
В чем смысл этого разделения, если все равно код выполняется последовательно и лучше всего будет выполняться в одном потоке, т.к. там не будет побочных потерь на переключение контекста потоков. :)


Название: Re: синхронизировать потоки и libpcap
Отправлено: verona от Январь 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...
я уже отключил все другие модули программы, сейчас только обозначенные потоки работают без всяких лишних операций  и ... по прежнему не работает.


Название: Re: синхронизировать потоки и libpcap
Отправлено: verona от Январь 10, 2013, 13:56
Да, но таково условие задачи
Это условие вытекает из плохого знания предмета топикстартером. В такой многозадачности просто нет смысла. :)

в будущем предполагается сделать circular buffer


Название: Re: синхронизировать потоки и libpcap
Отправлено: Old от Январь 10, 2013, 15:56
в будущем предполагается сделать circular buffer
В каком будущем? :)
То что ты пытаешься сделать - это вообще не решение. Ты однопоточное решение хочешь разбить на несколько потоков, так не получиться, оно по прежнему будет однопоточное.
Нужна очередь, куда поток слушающий pcap будет складывать данные, а один или несколько потоков-обработчиков будут эти данные из очереди брать и обрабатывать.


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

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

Мда...


Название: Re: синхронизировать потоки и libpcap
Отправлено: Igors от Январь 10, 2013, 18:55
Но ТС упорно продолжает гнуть свою линию с какой-то хренотенью в которой не разбирается и все усложняет.  :-\
Вполне возможно (и даже очень вероятно) что предложенное Вами решение по-любому лучше. Но все же не стоит его навязывать. В этой теме человек спросил конкретный вопрос - ну и дадим конкретный ответ. А "зачем так делать" - то его проблемы, вот спросит как лучше, тогда и ответим  :)

сделал как показали через семафоры, единственное объявил их как public члены mainwidget, соот-во доступ к ним из потоков происходит вот так: mw->semaphore1...
я уже отключил все другие модули программы, сейчас только обозначенные потоки работают без всяких лишних операций  и ... по прежнему не работает.
Впечатление что Вы как-то легкомысленно относитесь к архитектуре своего приложения. Быстренько попробовать - ага, не получилось, значит другое попробовать и.т.д. Разбираться надо где, что и как не работает.


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

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

Мда...

а как решить проблему с высокой загрузкой CPU ?