crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V  < 1 2 3 >  
Ответить в данную темуНачать новую тему
> QThread, QEvent, QTcpServer, взаимодействия между потоками
ViGOur
  опции профиля:
сообщение 12.11.2008, 8:29
Сообщение #11


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(512es @ 12.11.2008, 0:43) *
через сигнал\слот что то не получилось, т.к. надо передать ещё несколько переменных..
Почему не получилось? Не вижу проблем в передаче каких бы то ни было переменных!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 12.11.2008, 13:06
Сообщение #12


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


вообще, это мой первый проект на Qt, потому прошу сильно ногами не бить =)

вот как я пытаюсь делать:
class NetServer : public QTcpServer
{
    Q_OBJECT
public:
    NetServer(QObject *parent = 0);
    QHash<int, PThread*> Users;
private:
    int CurrentThreadNum;
protected:
    void incomingConnection(int socketDescriptor);
    void customEvent(QEvent *event);
};

void NetServer::incomingConnection(int socketDescriptor)
{
    Users.insert(++CurrentThreadNum,new PThread(socketDescriptor, this));
//    connect(this, SIGNAL(toSendMessage(QString msgString)), Users.value(CurrentThreadNum), SLOT(onSendMessage(QString msgString)));
    Users.value(CurrentThreadNum)->ThreadNumber = CurrentThreadNum;
    Users.value(CurrentThreadNum)->start();
}

void NetServer::customEvent(QEvent *event)
{
    QHashIterator<int, PThread*> i(Users);
    switch ((int)event->type()) {
    case 1234:
        MyNewMsgEvent *MyMsgEvent = (MyNewMsgEvent *)event;
        qDebug() << "Received custom Event text from user" << MyMsgEvent->SenderUser << MyMsgEvent->message;      
        while (i.hasNext()) {
            i.next();
//            i.value()->onSendMessage(QString::number(MyMsgEvent->SenderUser,10) + " " + MyMsgEvent->message);
//            qDebug() << i.value() << "ddd" << Users.value(1) << i.value()->currentThread();
            MyNewMsgEvent *ev = new MyNewMsgEvent();
            ev->message = MyMsgEvent->message;
            ev->SenderUser = MyMsgEvent->SenderUser;
            QCoreApplication::postEvent(i.value(), ev);
        }
        break;
    case 1109: // User disconnected
        EventDisconnected *EvDisconnected = (EventDisconnected *)event;
        qDebug() << "User" << EvDisconnected->SenderUser << "SignOff";
        Users.value(EvDisconnected->SenderUser)->deleteLater();
        Users.remove(EvDisconnected->SenderUser);
        qDebug() << "Stats" << Users.size();
        break;
    }
}

void PThread::onDisconnected()
{
    exit();
    EventDisconnected *ev = new EventDisconnected();
    ev->SenderUser = ThreadNumber;
    QCoreApplication::postEvent(this->parent(), ev);
}

void PThread::run()
{
    tcpSocket = new QTcpSocket;
    ...
    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()),Qt::DirectConnection);
    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(onDisconnected()),Qt::DirectConnection);
    exec();
    ...
    delete tcpSocket;
}

void PThread::customEvent(QEvent *event)
{
    switch ((int)event->type()) {
    case 1234:
        forever;
        break;
    }
}


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

так вот, проблема в том что PThread::customEvent(QEvent *event) выполняется почему то в главном потоке( хотя по идее должен в дочернем..
это можно наглядно увидеть через Process Explorer. когда доходит до цикла forever вешается главный поток, а не дочерний(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 12.11.2008, 15:02
Сообщение #13


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


попробовал через сигнал\слот..
connect(this, SIGNAL(toSendMessage(QString)), Users.value(CurrentThreadNum), SLOT(onSendMessage(QString)),Qt::DirectConnection);

всё равно в том же потоке выполняется =(
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 13.11.2008, 12:27
Сообщение #14


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


вообщем, всю голову сломал, не знаю как сделать(

http://trolltech.com/developer/faqs/faq.20...0-02.9810372345
написано что есть 3 способа:
1) передача эвентов
2) QCoreApplication::invokeLater()
3) и сигнал\слот с QueuedConnection

но к сожалению всё сказаное там для явы..

пробовал эвенты и через сигнал\слот с QueuedConnection.

пробовал даже вызывать метод в котором эмитится сигнал по которому вызывается нужный слот, как тут:
http://forum.sources.ru/index.php?showtopic=245838&hl=

результат один и тот же(


обгуглил весь инет, народ, не ужели никто не знает как вызывать метод из класса дочернего потока чтобы он выполнился в том самом дочернем а не в главном?


на ум приходит ещё один оч кривой способ..
отказаться от родителя в дочерних потоках и добавить в нужные методы moveToThread(this)
иии.. вот только что родилась идея ещё хуже.. пересылать данные по TCP на локалхост соединению между главным и дочерними потоками =)) бред..
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 13.11.2008, 13:17
Сообщение #15


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(512es @ 13.11.2008, 12:27) *
не ужели никто не знает как вызывать метод из класса дочернего потока
Я знаю, но судя по обсуждению ты не понял, что и как делать, потому мне пример писать нужно, а времени пока увы нет. :(

Честно говоря там ничего сложного нет...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 13.11.2008, 14:30
Сообщение #16


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Вот я пример набросал, правда с рисованием, но думаю идея будет понятна... :)
Раскрывающийся текст
main.cpp
#include <QtCore/QCoreApplication>

#include "xThread.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    CxThread thread[2];
    for( int n=0; n < sizeof( thread)/sizeof( *thread); ++n)
    {
        thread[n].start();
    }

    while( true)
    {
        for( int n=0; n < sizeof( thread)/sizeof( *thread); ++n)
        {
            if( thread[n].isRunning())
                emit thread[n].drawText();
        }
        thread[0].sleep( 1);
        qDebug( "**********************");
    }

    return a.exec();
}

xThread.h
#ifndef XTHREAD_H
#define XTHREAD_H

#include <QThread>
#include <QMutex>

class CxPrint;

class CxThread : public QThread
{
    Q_OBJECT

private:
    static QMutex m_mutex;
    int        m_n;
    CxPrint *m_pPrint;

public:
    CxThread(QObject *parent=0);
    ~CxThread();

    void drawText();
    static void sleep ( unsigned long uls);
    int GetN()const { return m_n; }

protected:
    virtual void run();
    
};

class CxPrint: QObject
{
    Q_OBJECT

public:
    void drawText();

signals:
    void signalDrawText();

protected slots:
    void slotDraw();

public:
    CxPrint(void);
    virtual ~CxPrint(void);
};


#endif // XTHREAD_H

xThread.cpp
#include "xThread.h"
#include "xPrint.h"

QMutex CxThread::m_mutex;

CxThread::CxThread(QObject *parent)    : QThread(parent)
{
    m_n=0;
    m_pPrint = 0;
}

CxThread::~CxThread()
{
    delete m_pPrint;
    m_pPrint = 0;
}

void CxThread::drawText()
{
    if( m_pPrint)
        emit m_pPrint->drawText();
}

void CxThread::sleep ( unsigned long uls)
{
    QThread::sleep( uls);
}

void CxThread::run()
{
    {
        QMutexLocker locker(&m_mutex);
        static int n = 1;
        m_pPrint = new CxPrint;
        qDebug( "Runing thread with id: 0x%x, thread N: %d", QThread::currentThreadId(), n);
        m_n = n;
        n++;
    }

    CxThread::exec();
}

CxPrint::CxPrint(void)
{
    connect( this, SIGNAL( signalDrawText()), this, SLOT( slotDraw()));
}

CxPrint::~CxPrint(void)
{
}

void CxPrint::slotDraw()
{
    qDebug( "Draw in thread with id: 0x%x, thread N: %d", QThread::currentThreadId(), ((CxThread*)QThread::currentThread())->GetN());
}

void CxPrint::drawText()
{
    emit signalDrawText();
}


Сообщение отредактировал ViGOur - 13.11.2008, 14:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 13.11.2008, 16:42
Сообщение #17


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


ViGOur, спасибо!) то что надо!))
у меня рождалась мысль что объект надо создавать в секции run() но уже не верилось что это заработает..
вообще жудко запутаная конструкция получилось, жаль что нельзя упростить.. хотяя...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 13.11.2008, 18:01
Сообщение #18


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(512es @ 13.11.2008, 16:42) *
ViGOur, спасибо!) то что надо!))
Не за что, обращайся еще... ;)

Цитата(512es @ 13.11.2008, 16:42) *
жаль что нельзя упростить..
Можно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
512es
  опции профиля:
сообщение 15.11.2008, 1:19
Сообщение #19


Участник
**

Группа: Участник
Сообщений: 135
Регистрация: 31.10.2008
Пользователь №: 407

Спасибо сказали: 5 раз(а)




Репутация:   0  


разве что от CxThread::drawText() удалось избавиться)

emit thread[n].drawText().m_pPrint.drawText()


вообще сервер работает быстро и надёжно) сколько бы не подключалось клиентов, пакеты им приходят моментально!)
отказался от эвентов, использую везде теперь только сигнал\слот =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 15.11.2008, 1:29
Сообщение #20


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(512es @ 15.11.2008, 4:19) *
вообще сервер работает быстро и надёжно) сколько бы не подключалось клиентов, пакеты им приходят моментально!)
Ну вот, а на пргорге тема о высоконагруженном сервере на Qt зашла в тупик (тык)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.6.2024, 16:44