Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt Синхронизация старта потоков 
:(
    Опции темы
feanor59
Дата 12.10.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



И так. Нужен совет. 
Цель: синхронизировать старт потоков, т. е. добиться, чтобы инструкция, следующая после abstractThread.start(); выполнялась только после выполнения метода abstractThread.run(); причём желательно организовать незанятое ожидание.

Ниже приведены пара моих решений. Если есть варианты лучше, отпишите.
Код

//Вариант 1:
//здесь не реализовано незанятое ожидание
for (; !abstractThread.isRunning(););

//Вариант 2:
//здесь приходится вызывать лишний метод

class AbsThread : public QThread {
QMutex mutex;
...
void run() {
...
exec();
mutex.unlock();
}

void prestart() {
mutex.lock();
}

public slots:
void allSlots (...) {
QMutexLocker locker(mutex);
...
}
...
};

AbsThread abstractThread;
abstractThread.prestart();
abstractThread.start();


Проблема же такая возникла из-за того, что в run() инициализируется объект QTextStream, но иногда до этого выполняется один из слотов, как следствие - краш.

Это сообщение отредактировал(а) feanor59 - 12.10.2008, 19:00
PM MAIL ICQ GTalk   Вверх
feanor59
Дата 12.10.2008, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



мда. как выяснилось, рабочий только 1й вариант, остальные воспринимаются как дедлок.
UPD:  чорд... 1й вариант так же не катит...

Это сообщение отредактировал(а) feanor59 - 12.10.2008, 19:28
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 13.10.2008, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Я что-то не понял... потоков сколько?

Цитата(feanor59 @  12.10.2008,  14:41 Найти цитируемый пост)
что в run() инициализируется объект QTextStream, но иногда до этого выполняется один из слотов, как следствие - краш.

Это тоже не понял.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
feanor59
Дата 13.10.2008, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



Цитата(JackYF @ 13.10.2008,  14:42)
Я что-то не понял... потоков сколько?

Цитата(feanor59 @  12.10.2008,  14:41 Найти цитируемый пост)
что в run() инициализируется объект QTextStream, но иногда до этого выполняется один из слотов, как следствие - краш.

Это тоже не понял.

поток один, не считая основного, и этот поток с этим основным и надо синхронизировать.
вот пример:

в потоке есть 2 метода:
Код

void Logger::run() {
    log = new QFile("log.htm");    
    logStream = new QTextStream(log);    

    exec();    
}

void Logger::slotLogIt(<something>) {
    logStream << "something" << endl;
}

main выглядит так
Код

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

    Logger logger(NULL);

    QObject::connect(udpClient.get(), SIGNAL(logIt(LogType, QString&)), &logger, SLOT(slotLogIt(LogType, QString&)));

    logger.start();
    for (int i = 0; i < 100; ++i)
        udpClient->sendMsg((QString)"PING");

    return a.exec();
}

Дак вот. Метод run() выполняется позже, чем emit logIt() в методе sendMsg().
Я в курсе, что инициализацию можно в конструктор вынести (точнее я так и сделал), но, тем не менее, проблема осталась, как минимум exec() выполняется позже, чем надо.

Это сообщение отредактировал(а) feanor59 - 13.10.2008, 15:02
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 14.10.2008, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Цитата(feanor59 @  13.10.2008,  14:01 Найти цитируемый пост)
Logger logger(NULL);
    QObject::connect(udpClient.get(), SIGNAL(logIt(LogType, QString&)), &logger, SLOT(slotLogIt(LogType, QString&)));
    logger.start();

Дык... сделай "logger.start()" до QObject::connect.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
feanor59
Дата 14.10.2008, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



Цитата(JackYF @ 14.10.2008,  14:53)
Цитата(feanor59 @  13.10.2008,  14:01 Найти цитируемый пост)
Logger logger(NULL);
    QObject::connect(udpClient.get(), SIGNAL(logIt(LogType, QString&)), &logger, SLOT(slotLogIt(LogType, QString&)));
    logger.start();

Дык... сделай "logger.start()" до QObject::connect.

не, не вариант. по разному пробовал. результат один.
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 14.10.2008, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



А впиши-ка debug output'ы в местах, которые должны быть синхронизированы.
Возможно, просто не ходят сообщения из-за того, что QCoreApplication ещё не запущен.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
feanor59
Дата 23.10.2008, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



так. извиняйте, что долго не отписывал, другие дела были. дак вот, качественное снабжение кода qDebug'ами выявили косяк следующего содержания. Инициализация QCoreApplication не успевает к первой высылке сигнала в коде, следовательно сигнал не высылается.
Я, правда, не совсем понимаю связь этого факта с проблемой старта потоков, но так или иначе проблема есть. Как то можно заставить код ждать инициализыции кор апликейшена и как всё таки это может помочь в разрешении проблемы потоков?
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 23.10.2008, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Цитата(feanor59 @  23.10.2008,  10:07 Найти цитируемый пост)
Как то можно заставить код ждать инициализыции кор апликейшена

вынести весь главный код main в отдельный поток? smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
feanor59
Дата 23.10.2008, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 24.1.2008
Где: Пермь

Репутация: нет
Всего: нет



кстати. хорошая идея. Вынести в поток всю инициализацию всего, что возможно, и повесить на это дело сплеш.
Попробую. 

UPD: а как это спасёт ситуацию с синхронизацией запуска потоков?

Это сообщение отредактировал(а) feanor59 - 23.10.2008, 19:50
PM MAIL ICQ GTalk   Вверх
JackYF
Дата 24.10.2008, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Тогда такой вариант: стартовать logger.start() только по сигналу, сделать emit сигнал перед app.exec(). Этот сигнал, по идее, будет выполнен после app.exec(), следовательно, к моменту запуска потока сигналы-слоты уже в строю.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0485 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.