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

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

Страниц: 1 2 [3] 4 5 6   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Помогите с задачей производителя/потребителя  (Прочитано 37954 раз)
Bepec
Гость
« Ответ #30 : Март 02, 2012, 20:52 »

Угу. Хорошая у тя моделька на сигнал слотах Подмигивающий

Ну таймера нету. Хотя это уже опционально Улыбающийся

Поток обрабатывает очередь сообщений, пока исполняется run.

Так же можно создать событийный поток вызвав QThread::run().

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

to lolbla2:

Читай про QTimer и допиливай его к этому проекту.

PS а я, добрый человек, по привычке без сигнал-слотов зафигачил программку Веселый вот до чего доводит пятница.
« Последнее редактирование: Март 02, 2012, 20:53 от Bepec » Записан
lolbla2
Гость
« Ответ #31 : Март 02, 2012, 20:54 »

Угу. Хорошая у тя моделька на сигнал слотах Подмигивающий

Ну таймера нету. Хотя это уже опционально Улыбающийся

Поток обрабатывает очередь сообщений, пока исполняется run.

Так же можно создать событийный поток вызвав QThread::run().

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

to lolbla2:

Читай про QTimer и допиливай его к этому проекту.

PS а я, добрый человек, по привычке без сигнал-слотов зафигачил программку Веселый вот до чего доводит пятница.

run всегда будет исполнятся, там бесконечные циклы
Записан
BRE
Гость
« Ответ #32 : Март 02, 2012, 20:56 »

Поток обрабатывает очередь сообщений, пока исполняется run.
Этим ты хочешь сказать, что поток будет обрабатывать сообщения без запуска exec() или ручного создания очереди?
« Последнее редактирование: Март 02, 2012, 21:07 от BRE » Записан
V1KT0P
Гость
« Ответ #33 : Март 02, 2012, 21:05 »

run всегда будет исполнятся, там бесконечные циклы
В самом QThread функция run имеет вид:
Код:
void QThread::run()
{
    (void) exec();
}
Так вот если после перегрузки ты не выполнишь exec() то не запустится механизм обработки сигнал/слотов. Учти что внутри exec() бесконечный цикл.

Короче добавил пару функций, вот то что ты хочешь с таймером: http://rghost.ru/36813776
Записан
Bepec
Гость
« Ответ #34 : Март 02, 2012, 21:25 »

Да. Как и в случае с "невидимым виджетом", у меня это работает, а у вас невозможно теоретически. А знаешь почему? Потому что тролли сначала думают, потом делают.
Посмотри на досуге метод start() Веселый

Записан
V1KT0P
Гость
« Ответ #35 : Март 02, 2012, 21:39 »

Да. Как и в случае с "невидимым виджетом", у меня это работает, а у вас невозможно теоретически. А знаешь почему? Потому что тролли сначала думают, потом делают.
Посмотри на досуге метод start() Веселый



Глянул но так и не понял что ты хотел сказать.
Код:
void QThread::start(Priority priority)
{
    Q_D(QThread);
    QMutexLocker locker(&d->mutex);

    if (d->isInFinish) {
        locker.unlock();
        wait();
        locker.relock();
    }

    if (d->running)
        return;

    d->running = true;
    d->finished = false;
    d->terminated = false;
    d->exited = false;
    d->returnCode = 0;

    d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start,
                                            this, CREATE_SUSPENDED, &(d->id));

    if (!d->handle) {
        qErrnoWarning(errno, "QThread::start: Failed to create thread");
        d->running = false;
        d->finished = true;
        return;
    }

    int prio;
    d->priority = priority;
    switch (d->priority) {
    case IdlePriority:
        prio = THREAD_PRIORITY_IDLE;
        break;

    case LowestPriority:
        prio = THREAD_PRIORITY_LOWEST;
        break;

    case LowPriority:
        prio = THREAD_PRIORITY_BELOW_NORMAL;
        break;

    case NormalPriority:
        prio = THREAD_PRIORITY_NORMAL;
        break;

    case HighPriority:
        prio = THREAD_PRIORITY_ABOVE_NORMAL;
        break;

    case HighestPriority:
        prio = THREAD_PRIORITY_HIGHEST;
        break;

    case TimeCriticalPriority:
        prio = THREAD_PRIORITY_TIME_CRITICAL;
        break;

    case InheritPriority:
    default:
        prio = GetThreadPriority(GetCurrentThread());
        break;
    }

    if (!SetThreadPriority(d->handle, prio)) {
        qErrnoWarning("QThread::start: Failed to set thread priority");
    }

    if (ResumeThread(d->handle) == (DWORD) -1) {
        qErrnoWarning("QThread::start: Failed to resume new thread");
    }
}
Записан
V1KT0P
Гость
« Ответ #36 : Март 02, 2012, 21:59 »

А знаешь почему?
Блин только что проверил, работает. Но с какого хрена оно так работает? Как заставить сигнал встать в очередь и не выполняться пока его не позовут.
Я все время думал что сигналы ждут пока поток не завершит выполнять функцию и только тогда выполняет следующую функцию.
Я во всех своих многопоточных программах использовал только сигналы вместо мьютексов. Пипец, это наверно у меня в коде где-то скрытые баги которые ждут своего времени  Обеспокоенный.
Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну.
Записан
BRE
Гость
« Ответ #37 : Март 02, 2012, 22:10 »

Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну.
Ты посмотри в чьем контексте отрабатываю твои слоты, думаю ты удивишься еще больше. Улыбающийся
Записан
V1KT0P
Гость
« Ответ #38 : Март 02, 2012, 22:30 »

Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну.
Ты посмотри в чьем контексте отрабатываю твои слоты, думаю ты удивишься еще больше. Улыбающийся

С какого хрена сигнал делает почти прямой вызов? Я же четко указываю Qt::QueuedConnection а не Qt::DirectConnection.

Цитировать
Signals

Signals are emitted by an object when its internal state has changed in some way that might be interesting to the object's client or owner. Only the class that defines a signal and its subclasses can emit the signal.

When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and slots mechanism is totally independent of any GUI event loop. Execution of the code following the emit statement will occur once all slots have returned. The situation is slightly different when using queued connections; in such a case, the code following the emit keyword will continue immediately, and the slots will be executed later.

If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.

Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void).

A note about arguments: Our experience shows that signals and slots are more reusable if they do not use special types. If QScrollBar::valueChanged() were to use a special type such as the hypothetical QScrollBar::Range, it could only be connected to slots designed specifically for QScrollBar. Connecting different input widgets together would be impossible.
В самой документации утверждается что слот должен выполниться позже. Что за хрень?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #39 : Март 03, 2012, 00:36 »

В аттаче подправленный вариант (используется UI что сделал V1KT0P). Если нажимать кнопку с интервалом 2 сек и более - consumer получит все что сделал producer. Если быстрее - строки будут теряться (что и требуется в задании)
Записан
lolbla2
Гость
« Ответ #40 : Март 03, 2012, 10:44 »

В аттаче подправленный вариант (используется UI что сделал V1KT0P). Если нажимать кнопку с интервалом 2 сек и более - consumer получит все что сделал producer. Если быстрее - строки будут теряться (что и требуется в задании)

Спасибо конечно, но что у тебя что у Viktor'a одинаково у вас, сообщения отправляет производитель и потребитель мгновенно принимает, ничего никогда не теряется.

P.S. задание чуток изменилось:

теперь надо чтобы сообщение не терялись.

поток 1-> по нажатию кнопки создаёт сообщения. кладёт в очередь. И если поток 2 готов принять сообщение, то берёт из очереди и отправляет.

поток 2-> ждёт каждые 2 секунды просматривает буфер. Если там чото есть считывает ( то есть этот поток моделирует некое устройство, которое способно только каждые 2 сек считывать). Пока поток 2 ждёт, поток 1 не должен в буфер ничего класть.
Записан
lolbla2
Гость
« Ответ #41 : Март 03, 2012, 10:49 »

Кстати мьютекс блокирует часть кода расположенную в пределах между
lock()
// код который заблокирован для доступа
 unlock() ?

а как заблокировать доступ к переменной?
Записан
Bepec
Гость
« Ответ #42 : Март 03, 2012, 10:55 »

ЛолБла2 - у тебя есть уже готовая программа, допиливай её сам и разбирайся. (И другим советую не писать ему программу, а то разлениться Подмигивающий)

Заблокировать доступ к переменной - закрыть мьютексами все функции, которые её запрашивают.

V1KT0P
Насчёт start я наверно погорячился Подмигивающий Выкобениться решил. Улыбающийся Каюсь.

Где то упоминалось, что при вызове метода start, а затем start вызываеь run, а затем run вызывает QThread::exec() в качестве скрытого приватного поля класса Подмигивающий

Виктор, LolBla2 - советую почитать http://habrahabr.ru/blogs/qt_software/115830/ (это не реклама, а статья по Qt, ежели Пантер обратит свой гнев на меня Подмигивающий )
Записан
BRE
Гость
« Ответ #43 : Март 03, 2012, 11:02 »

Где то упоминалось, что при вызове метода start, а затем start вызываеь run...
Точнее start создает новый поток в котором и выполняет метод run. А реализация run из QThread, как раз запускает exec, для обработки очереди событий.
Если ты сам переопределяешь run и не запускаешь очередь событий, то события обрабатываться не будут. Чудес не бывает.

а затем run вызывает QThread::exec() в качестве скрытого приватного поля класса Подмигивающий
Расскажи подробней про эту новую возможность С++.
Записан
Bepec
Гость
« Ответ #44 : Март 03, 2012, 11:07 »

BRE сделай проект. Переопредели RUN в бесконечный цикл и сделай 1 слот, без exec().

Сконеекть, отэмить сконнекченный сигнал из основного потока в созданный. Слот выполнится или нет? Улыбающийся

Насколько я помню, BRE, ты уже агрился на меня в теме "Невидимый плагин для дизайнера", а под конец, поняв о чём речь, постыдно убежал...

Напомню:
to BRE: Без вмешательства пользователя плагин будет прилинкован к проекту, если его перетащить в дизайнере. Никаких "ручных" правок *.pro , линковок проекта, добавления в свойства проекта необходимых путей. Пользователь перетащит и будет пользоваться, заместо "ковыряния, линковок".
Я был против "ручками дописываем в *.pro, прописываем путь в **, собираем".
К сожалению это не возможно. Как только ты перестанешь мечтать и хотя бы залезешь в примеры, то ты все это увидишь сам.
А под конец неожиданно мир изменился и это стало возможно.
Совет: Проверяй сначала сам. Не обо всём в учебниках пишут.
Записан
Страниц: 1 2 [3] 4 5 6   Вверх
  Печать  
 
Перейти в:  


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