Название: [РЕШЕНО] Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 01, 2012, 17:23 Почему-то на разных компах по-разному работает. Потоки такая вещь что они вообще иногда так странно себя ведут однако.
Вообщем, суть в следующем, производитель создаёт символ и передаёт его потребителю. Всё это синхронизировано мютексами и QWaitCondition. Пример взял из документации, пытаюсь его сделать под GUI, ибо там консольное. Хочу чтобы они у меня в реальном времени символы выводили, то есть производитель создал символ и вывел его, потребитель, получил тоже вывел в textBrowser. ПОка получилось сделать только чтобы по окончанию работы выводился весь буффер символов. В реальном времени не получается что-то, всё повисает. ВОт код: consumer Код
producer Код
Код
Помогите зделать реалтайм вывод в GUI... P.S.: чот и такой вариант иногда повисает и ничего не выводит, потоки как-то случайно работают, не понимаю я их порой(( ??? Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 01, 2012, 17:48 ААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА....
Мой моск взорвался при виде этого кода... PS to Пантер - реально... Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 01, 2012, 18:03 ААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА.... Мой моск взорвался при виде этого кода... PS to Пантер - реально... Ну подскажи как правильно) Я не особо давно пользуюсь Qt. Наверно 3 месяц Название: Re: Помогите с задачей производителя/потребителя Отправлено: Пантер от Март 02, 2012, 09:21 ААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА.... Ну нельзя же так в пятницу с утра с похмелья!Мой моск взорвался при виде этого кода... PS to Пантер - реально... lolbla2, тут даже не знаю, что и сказать. У тебя все неверно. Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 02, 2012, 12:34 lolbla2, тут даже не знаю, что и сказать. У тебя все неверно. А что неверно? Вроде все правильно (откуда-то списано)Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 13:33 Скажу проще - тем, что у тебя тут написано, можно пытать программистов(ну или если ток я так думаю, то меня пытать :D ) :D
Вместо изящных, простых конструкций - у тебя чугунная заготовка с афигительным количеством углов, об которые можно биться головой. PS при попытке разобраться, мозг берёт выходной... Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 02, 2012, 14:01 Вместо изящных, простых конструкций - Ну если Вы такой эстет - никто не мешает показать лучшее, более элегантное решение. А охаять чужой код - много ума не надо :)Кстати, хотя пример из букваря (сейчас посмотрел) мне кажется что он не будет работать правильно с 2 или более consumer'ами И возвращаясь к первоисточнику - ну и ставьте emit вместо вывода в qDebug() - только обязательно с QueuedConnection Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 14:06 Я прост сегодня переписывал свою многопточку. День работы на вставку комментариев, уборку хлама и придания чистоты "Белизной".
До сих пор под впечатлением ;) update: Если кого и обидел, простите :P Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 14:44 ААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА.... Ну нельзя же так в пятницу с утра с похмелья!Мой моск взорвался при виде этого кода... PS to Пантер - реально... lolbla2, тут даже не знаю, что и сказать. У тебя все неверно. а что конкретно? предложи тогда свой вариант? Блин столько комментов, ни одного по теме((( Вообщем задача чуток поменялась надо вот что: Разработать приложение, состоящее из двух функциональных частей. Первая время от времени отправляет сообщения (например, это может происходить при нажатии некоторой кнопки, или клавиши на клавиатуре) второй, вторая каким-то образом на них реагирует. Размер буфера передачи между этими частями – 1 сообщение, а первая задача (передатчик) никогда не ждет очистки буфера. Т.е. если вторая часть (приемник) не успевает получить помещенное в буфер сообщение, а уже возникает новое сообщение, то это новое сообщение заменяет старое, а старое - теряется. Здесь передатчик имитирует аппаратное обеспечение СРВ. Время обработки сообщения приемником должно быть 1-2с (можно воспрользоваться функцией Sleep). Необходимо добиться того, чтобы при возникновении 2-3 сообщений подряд (до окончания обработки первого из них) ни одно из них не терялось, т.е. все обрабатывались приемником. Ожидается использование таких синхронизационных примитивов, как событие, критическая секция или мьютекс. Возможно использование семафоров или семейства Interlocked-функций. Предлагается такая схема работы. Кроме главного, создаются еще два потока. Один из них с нужной частотой пишет в «буфер» (тот самый, размер которого – одно сообщение) какие-то символы, а другой, как только в буфере появляется символ, читает его оттуда и помещает в какой-то свой буфер. Главный же поток ждет, пока в этом втором буфере появится очередной символ, и затем его «обрабатывает» (например, выводит на экран). Второй буфер должен быть достаточно большим, чтобы вместить 2-3 сообщения (см. условие задачи), где они будут ожидать, пока главный поток их не обработает. Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 14:48 Вместо изящных, простых конструкций - Ну если Вы такой эстет - никто не мешает показать лучшее, более элегантное решение. А охаять чужой код - много ума не надо :)Кстати, хотя пример из букваря (сейчас посмотрел) мне кажется что он не будет работать правильно с 2 или более consumer'ами И возвращаясь к первоисточнику - ну и ставьте emit вместо вывода в qDebug() - только обязательно с QueuedConnection а мне и не надо 2 и более Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 02, 2012, 15:04 Задача у Вас простейшая. Есть общий буфер обмена, передатчик и приемник пишут/читают его под мутексом. Поэтому если приемник не успеет - передатчик перекроет (как Вам и надо). Записав данные передатчик просто отправляет приемнику сигнал "есть данные" (без параметров). Все.
Блин столько комментов, ни одного по теме((( Ответы не обязаны Вам нравиться. Будете еще фыркать, хохотать - перестану отвечать :)Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 15:07 2 потока, 2 буфера, 2 функции, 1 мьютекс...
А не отвечают по теме, ибо у вас вопрос невнятный. Ваш код нужно не править - вам нужно новую программу написать. Так будет легче и проще. PS ну чесслово я посмотрю на код и глаза расходятся ;) Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 19:33 2 потока, 2 буфера, 2 функции, 1 мьютекс... А не отвечают по теме, ибо у вас вопрос невнятный. Ваш код нужно не править - вам нужно новую программу написать. Так будет легче и проще. PS ну чесслово я посмотрю на код и глаза расходятся ;) Ну да я тоже так и думал но когда начал реализовывать почему-то так просто не получается... Изменил код вот так: Код
и потребитель Код
ну и запускаю потоки кнопкой вот так: Код а другой кнопкой посылаю сигнал о том, чтобы производитель добавил новое сообщение: Код
Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 19:46 PS ну чесслово я посмотрю на код и глаза расходятся ;) +1 Вот и хочется человеку помочь, а от одного взгляда на код все желание пропадает.Ну да я тоже так и думал но когда начал реализовывать почему-то так просто не получается... Сделай минимальный рабочий пример. Мне все-равно еще 3 часа делать нечего, а так может и помогу.Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 19:50 PS ну чесслово я посмотрю на код и глаза расходятся ;) +1 Вот и хочется человеку помочь, а от одного взгляда на код все желание пропадает.Ну да я тоже так и думал но когда начал реализовывать почему-то так просто не получается... Сделай минимальный рабочий пример. Мне все-равно еще 3 часа делать нечего, а так может и помогу.ну вот предпоследний пост мой меньше кода вроде более разборчивый. Могу исходник прикрепить если так проще будет... Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 19:57 ну вот предпоследний пост мой меньше кода вроде более разборчивый. Могу исходник прикрепить если так проще будет... Конечно проще, ибо создавать новый проект и туда добавлять код лениво. А так скачал запустил, увидел, изменил, отослал.Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:11 ну вот предпоследний пост мой меньше кода вроде более разборчивый. Могу исходник прикрепить если так проще будет... Конечно проще, ибо создавать новый проект и туда добавлять код лениво. А так скачал запустил, увидел, изменил, отослал.вот пожалуйста Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:14 lolbla2 - тебе нужна программа, сама записывающая в 1 потоке символ, вторым потоком реагирует, вытаскивает этот символ и выводит в гуи?
Буфер между потоками -1 символ(сообщение), буфер основного потока - бесконечный? И самый значимый - тебе точно не надо 2 отдельных приложения? :) И да, где у тебя буфер должен быть быть??? Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:20 lolbla2 - тебе нужна программа, сама записывающая в 1 потоке символ, вторым потоком реагирует, вытаскивает этот символ и выводит в гуи? Буфер между потоками -1 символ(сообщение), буфер основного потока - бесконечный? И самый значимый - тебе точно не надо 2 отдельных приложения? :) да мне нужно именно первое что ты сказал, но правда я не понял что за бесконечный буфер основного потока? кстати потребитель читает раз в 2 секунды, то есть производитель сует новые символы, а потребитель не успевает, значит символы теряются. Символы сувать сначала в очередь сообщений по нажатию кнопки, а поток производитель поочерёдно из очереди суёт в общий буфер, ну и там уже что успеет считать потребитель, ибо он раз в 2 сек считывает, а производитель без остановок сует в буфер символы. Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:23 Эм. ЛолБла2 - то, что ты сейчас пытаешься сказать это извращение )
Обычное лабораторное какое-то извращение. Проще говоря надо раз в 2 секунды(допустим) очищать промежуточный буфер? update: Ты определись где у тебя очередь ) Т.е. символы не могут идти кучей, а идут последовательно с промежутком в 2 сек. Хотяя... Код: /* не читай, это размышления :D Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:30 Эм. ЛолБла2 - то, что ты сейчас пытаешься сказать это извращение ) Обычное лабораторное какое-то извращение. Проще говоря надо раз в 2 секунды(допустим) очищать промежуточный буфер? update: Ты определись где у тебя очередь ) Т.е. символы не могут идти кучей, а идут последовательно с промежутком в 2 сек. Хотяя... Код: /* не читай, это размышления :D ты мну неправильно понял, посылает без пауз, а считывает с паузами, ну да противное извращение конечно.... согласен просто в буфере может быть только 1 символ, поэтому записываются туда по одному непрерывно. А считываются другим потоком каждые 2 сек. Ну и понятное дело он будет не все символы успевать считать. в гуи выводить в таббрпаузер то что один поток записывал в буфер, а в другом тамбраузере то что второй поток успел считать Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:36 Так. Сосредоточься.
Поток1 -> непрерывная запись(или в любое время) символов в буфер. Поток2 -> считывание раз в 2 секунды???? Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:36 Эм. ЛолБла2 - то, что ты сейчас пытаешься сказать это извращение ) Обычное лабораторное какое-то извращение. Проще говоря надо раз в 2 секунды(допустим) очищать промежуточный буфер? update: Ты определись где у тебя очередь ) Т.е. символы не могут идти кучей, а идут последовательно с промежутком в 2 сек. Хотяя... Код: /* не читай, это размышления :D а вообще у меня такая проблема: почему поток не принимает сигналы от гуи? кнопкой шлю сигналы, а они до слота поток не доходят(( Ну это если не смотреть глобально на мою задачу, а хотя бы такую помощью прошу оказать)) :) Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:38 Так. Сосредоточься. Поток1 -> непрерывная запись(или в любое время) символов в буфер. Поток2 -> считывание раз в 2 секунды???? По нажатию кнопки в очередь суём символы. Поток1 -> непрерывная запись(или в любое время) символов в буфер если они имеются в очереди символов. Поток2 -> считывание раз в 2 секунды ВОт так верно Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:39 С первым потоком определись. Там у тебя или запись в любое время, или же запись с каким то промежутком?
Да, и ещё, пустой буфер потоков выводить, иль буфер никогда не очищается? Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 20:40 а вообще у меня такая проблема: почему поток не принимает сигналы от гуи? Потому что ты не даешь ему обработать сигналы.Код: void run() Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:41 Неправильный ответ - V1KT0P.
Для приёма сигналов нет необходимости в exec(); Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:44 С первым потоком определись. Там у тебя или запись в любое время, или же запись с каким то промежутком? Да, и ещё, пустой буфер потоков выводить, иль буфер никогда не очищается? если там пусто то не читать оттуда. поток 1-> в бесконечном цикле читает сообщения из очереди сообщений, если в очереди чото есть, взять оттуда и записать в общий буфер, записанный символ вести в гуи ( в таббраузер). поток 2 -> если буфер не пустой, подождать 2 сек и считать оттуда символ и вывести в гуи( в другой таббраузер). Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 20:44 Неправильный ответ - V1KT0P. Ну и как же поток обработает сигнал, если он даже не проверяет список принятых сигналов?Для приёма сигналов нет необходимости в exec(); Вот я вижу это примерно вот так: http://rghost.ru/36813315 (http://rghost.ru/36813315) Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:49 Неправильный ответ - V1KT0P. Ну и как же поток обработает сигнал, если он даже не проверяет список принятых сигналов?Для приёма сигналов нет необходимости в exec(); Вот я вижу это примерно вот так: http://rghost.ru/36813315 (http://rghost.ru/36813315) Спасибо конечно, но к сожалению это не то :( У тебя получается один отсылает другой сразу же принимает. А другой должен читать буффер только каждые 2 сек Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 20:52 Угу. Хорошая у тя моделька на сигнал слотах ;)
Ну таймера нету. Хотя это уже опционально :) Поток обрабатывает очередь сообщений, пока исполняется run. Так же можно создать событийный поток вызвав QThread::run(). А exec создаст свой отдельную очередь событий, которую потом прибивать придётся ручками ;) to lolbla2: Читай про QTimer и допиливай его к этому проекту. PS а я, добрый человек, по привычке без сигнал-слотов зафигачил программку :D вот до чего доводит пятница. Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 02, 2012, 20:54 Угу. Хорошая у тя моделька на сигнал слотах ;) Ну таймера нету. Хотя это уже опционально :) Поток обрабатывает очередь сообщений, пока исполняется run. Так же можно создать событийный поток вызвав QThread::run(). А exec создаст свой отдельную очередь событий, которую потом прибивать придётся ручками ;) to lolbla2: Читай про QTimer и допиливай его к этому проекту. PS а я, добрый человек, по привычке без сигнал-слотов зафигачил программку :D вот до чего доводит пятница. run всегда будет исполнятся, там бесконечные циклы Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 02, 2012, 20:56 Поток обрабатывает очередь сообщений, пока исполняется run. Этим ты хочешь сказать, что поток будет обрабатывать сообщения без запуска exec() или ручного создания очереди?Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 21:05 run всегда будет исполнятся, там бесконечные циклы В самом QThread функция run имеет вид:Код: void QThread::run() Короче добавил пару функций, вот то что ты хочешь с таймером: http://rghost.ru/36813776 (http://rghost.ru/36813776) Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 02, 2012, 21:25 Да. Как и в случае с "невидимым виджетом", у меня это работает, а у вас невозможно теоретически. А знаешь почему? Потому что тролли сначала думают, потом делают.
Посмотри на досуге метод start() :D Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 21:39 Да. Как и в случае с "невидимым виджетом", у меня это работает, а у вас невозможно теоретически. А знаешь почему? Потому что тролли сначала думают, потом делают. Посмотри на досуге метод start() :D Глянул но так и не понял что ты хотел сказать. Код: void QThread::start(Priority priority) Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 21:59 А знаешь почему? Блин только что проверил, работает. Но с какого хрена оно так работает? Как заставить сигнал встать в очередь и не выполняться пока его не позовут.Я все время думал что сигналы ждут пока поток не завершит выполнять функцию и только тогда выполняет следующую функцию. Я во всех своих многопоточных программах использовал только сигналы вместо мьютексов. Пипец, это наверно у меня в коде где-то скрытые баги которые ждут своего времени :-[. Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну. Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 02, 2012, 22:10 Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну. Ты посмотри в чьем контексте отрабатываю твои слоты, думаю ты удивишься еще больше. :)Название: Re: Помогите с задачей производителя/потребителя Отправлено: V1KT0P от Март 02, 2012, 22:30 Сигнал что прерывает выполнение текущей функции? Как сделать чтоб сигнал лежал в очереди, я же теперь не засну. Ты посмотри в чьем контексте отрабатываю твои слоты, думаю ты удивишься еще больше. :)Цитировать 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. Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 03, 2012, 00:36 В аттаче подправленный вариант (используется UI что сделал V1KT0P). Если нажимать кнопку с интервалом 2 сек и более - consumer получит все что сделал producer. Если быстрее - строки будут теряться (что и требуется в задании)
Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 10:44 В аттаче подправленный вариант (используется UI что сделал V1KT0P). Если нажимать кнопку с интервалом 2 сек и более - consumer получит все что сделал producer. Если быстрее - строки будут теряться (что и требуется в задании) Спасибо конечно, но что у тебя что у Viktor'a одинаково у вас, сообщения отправляет производитель и потребитель мгновенно принимает, ничего никогда не теряется. P.S. задание чуток изменилось: теперь надо чтобы сообщение не терялись. поток 1-> по нажатию кнопки создаёт сообщения. кладёт в очередь. И если поток 2 готов принять сообщение, то берёт из очереди и отправляет. поток 2-> ждёт каждые 2 секунды просматривает буфер. Если там чото есть считывает ( то есть этот поток моделирует некое устройство, которое способно только каждые 2 сек считывать). Пока поток 2 ждёт, поток 1 не должен в буфер ничего класть. Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 10:49 Кстати мьютекс блокирует часть кода расположенную в пределах между
lock() // код который заблокирован для доступа unlock() ? а как заблокировать доступ к переменной? Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 10:55 ЛолБла2 - у тебя есть уже готовая программа, допиливай её сам и разбирайся. (И другим советую не писать ему программу, а то разлениться ;))
Заблокировать доступ к переменной - закрыть мьютексами все функции, которые её запрашивают. V1KT0P Насчёт start я наверно погорячился ;) Выкобениться решил. :) Каюсь. Где то упоминалось, что при вызове метода start, а затем start вызываеь run, а затем run вызывает QThread::exec() в качестве скрытого приватного поля класса ;) Виктор, LolBla2 - советую почитать http://habrahabr.ru/blogs/qt_software/115830/ (это не реклама, а статья по Qt, ежели Пантер обратит свой гнев на меня ;) ) Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:02 Где то упоминалось, что при вызове метода start, а затем start вызываеь run... Точнее start создает новый поток в котором и выполняет метод run. А реализация run из QThread, как раз запускает exec, для обработки очереди событий.Если ты сам переопределяешь run и не запускаешь очередь событий, то события обрабатываться не будут. Чудес не бывает. а затем run вызывает QThread::exec() в качестве скрытого приватного поля класса ;) Расскажи подробней про эту новую возможность С++.Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:07 BRE сделай проект. Переопредели RUN в бесконечный цикл и сделай 1 слот, без exec().
Сконеекть, отэмить сконнекченный сигнал из основного потока в созданный. Слот выполнится или нет? :) Насколько я помню, BRE, ты уже агрился на меня в теме "Невидимый плагин для дизайнера", а под конец, поняв о чём речь, постыдно убежал... Напомню: to BRE: Без вмешательства пользователя плагин будет прилинкован к проекту, если его перетащить в дизайнере. Никаких "ручных" правок *.pro , линковок проекта, добавления в свойства проекта необходимых путей. Пользователь перетащит и будет пользоваться, заместо "ковыряния, линковок". К сожалению это не возможно. Как только ты перестанешь мечтать и хотя бы залезешь в примеры, то ты все это увидишь сам.Я был против "ручками дописываем в *.pro, прописываем путь в **, собираем". Совет: Проверяй сначала сам. Не обо всём в учебниках пишут. Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:16 Сконеекть, отэмить сконнекченный сигнал из основного потока в созданный. Слот выполнится или нет? :) А ты проверь в каком контексте он выполняется. Ты даже не понял куда нужно посмотреть, хотя в этой теме я писал подсказку для V1KT0P, с которым мы во всем разобрались, правда в привате. :)Насколько я помню, BRE, ты уже агрился на меня в теме "Невидимый плагин для дизайнера", а под конец, поняв о чём речь, постыдно убежал... Куда я убежал? Я вспомнил о этой возможности сам, случайно. А ты даже не смог ее сформулировать, потому что даже не знаешь как это все работает.Лепетал просто: "Ну у меня же работает...". Как в ералаше: "Ну я же изобрел...". :) Думаю не сможешь этого объяснить и сейчас. А почему пост pastor оставил без ответа, не нашел что сказать? Ты нахватался вершков и давай писать кучу своих домыслов во всех темах. Это утомляет, времени не хватает ходить по всем темам, где ты пишешь и поправлять за тобой. Совет: Проверяй сначала сам. Не обо всём в учебниках пишут. Распечатай и повесь себе на монитор. :)Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 11:19 Верес я на самом деле хотел бы сам решить эту задачу, но у меня возникают мелкие вопросы, на которые бы хотел бы тут получать ответы, вопросы, например как про мьютекс. Статья интересная обязательно прочту. У меня ещё вопрос: а этот exec() можно в начале метода run прописывать, если у меня в run бесконечный цикл, то если поставить exec() в конце, тогда дело до него дойдёт...
Код
Вопрос 2: Зачем нужен QMutexLocker ? Ведь у QMutex есть lock() и unlock()... Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:24 У меня ещё вопрос: а этот exec() можно в начале метода run прописывать, если у меня в run бесконечный цикл, то если поставить exec() в конце, тогда дело до него дойдёт... exec по сути тоже запускает бесконечный цикл, в котором происходит обработка событий, поэтому при таком коде выполнение до твоего бесконечного цикла не дойтет, пока будет выполняться цикл из exec.Можно добавить свою обработку событий прямо в твой бесконечный цикл, см. QEventLoop. Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:27 Вопрос 2: Зачем нужен QMutexLocker ? Ведь у QMutex есть lock() и unlock()... Это позволяет автоматизировать разблокировку мьютекса, что бы ты не забыл.Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:27 У меня работает, а ты отвечаешь что нет ;) Сигнал мой выполняется в доп потоке ;) Иначе не было бы смысла в моих программах ;) Так что BRE успокойся и начинай проверять.
Я незнаю некоторых простых вещей. Я не могу точно и детально тебе объяснить что и где, НО. Но я сначала проверяю. Работает - гуд. Не работает - надо разбираться. Согласись - всё знать нереально, а ту часть, что тебе нужна - реально ;) lolbla2 - у тебя в нём нет необходимости, помоему ;) Ибо exec() создаёт точно такой же бесконечный цикл, как и у тебя. Проще говоря, это 2 варианта: 1) зацикленный поток, он будет выполняться до тех пор, пока ты его не остановишь. (с помощью того же сигнала или напрямую не изменишь перем stop) Код: // bool stop = false; Код: void run() В чём недостатки и преимущества? 1 вариант, когда надо выполнить что-то определённое кол-во раз и убить поток по правильному. (правильное убиение потока - его логическое завершение ф-ции run()) 2 вариант, когда нужно выполнять ф-ции по требованию, как у тебя например. Тыкнул пользователь кнопочку - сигнал пошёл - поток проснулся, выполнил, опять спит. Вот ток убивать его нужно exit'ом. Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:29 У меня работает, а ты отвечаешь что нет ;) Оно у тебя работает как QSound? :)Иначе не было бы смысла в моих программах ;) ::)Название: Re: Помогите с задачей производителя/потребителя Отправлено: mutineer от Март 03, 2012, 11:29 BRE сделай проект. Переопредели RUN в бесконечный цикл и сделай 1 слот, без exec(). Сконеекть, отэмить сконнекченный сигнал из основного потока в созданный. Слот выполнится или нет? :) Если создавать слот у потомка QThread и коннектиться к нему через очередь, то довольно опрометчиво ожидать, что он будет выполняться в потоке, которым управляет этот потомок QThread (если не делать извращений типа moveToThread(this)) А если коннектиться не через очередь, то и eventLoop не нужен для вызова Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:32 multineer, вопрос, а почему moveToThread извращение? :)
Как иначе ты поместишь класс, нужный тебе, в другой поток? Тролли даже рекомендуют разделять управляющую и исполняемую часть потоков знаешь как? Код: QThread *thread = new QThread; За точность кода не ручаюсь ;) Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 11:33 Вопрос 2: Зачем нужен QMutexLocker ? Ведь у QMutex есть lock() и unlock()... Это позволяет автоматизировать разблокировку мьютекса, что бы ты не забыл.Не понял... Как именно автоматизировать, можно пример? unlock() же разблокирует... P.S. У вас тут интеллектуальный бой за звание лучший программист?))) Название: Re: Помогите с задачей производителя/потребителя Отправлено: mutineer от Март 03, 2012, 11:34 multineer, вопрос, а почему moveToThread извращение? :) Как иначе ты поместишь класс, нужный тебе, в другой поток? Тролли даже рекомендуют разделять управляющую и исполняемую часть потоков знаешь как? Код: QThread *thread = new QThread; За точность кода не ручаюсь ;) извращение - это делать moveToThread(this) - то есть пихать объект QThread внутрь подконтрольного ему же потока Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:35 Не понял... Как именно автоматизировать, можно пример? В документации к этому классу есть отличный пример, как с ним и как без него. :)Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:36 P.S. У вас тут интеллектуальный бой за звание лучший программист?))) Скорее попытка донести, что чудес не бывает. :)Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:39 Код: void send Тут не бой. Тут попытка выкоежиться у BRE. Уже была один раз, но к сожалению он провалил её, убежав с поля боя ;) Название: Re: Помогите с задачей производителя/потребителя Отправлено: mutineer от Март 03, 2012, 11:40 Вопрос 2: Зачем нужен QMutexLocker ? Ведь у QMutex есть lock() и unlock()... Это что бы ты вызвав lock() случайно не забыл вызвать unlock() Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 11:44 Тут не бой. Тут попытка выкоежиться у BRE. Тут попытка избавить человека от потока непроверенного бреда. Уже была один раз, но к сожалению он провалил её, убежав с поля боя ;) А о чем можно разговаривать с человеком, который понятия не имеет о предмете разговора?Который, кстати, ушел из темы сам, решив не отвечать на неудобные вопросы на которые он ответов не знал. Возвращайся к "Мурзилке"... :) Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:46 Так же очень здорово помогает в конструкциях типо
Код: QMutexLocker locker(&lock); Вместо 4 строк, о которых можно забыть, есть только 1 класс ;) toBRE: если несложно, то можешь почитать о создании плагина к дизайнеру в ассистанте ;) Qt служит для закрытия от программиста внутренних механизмов. А ты начинаешь всё раскапывать, углубляясь в далёёёкие дебри своего незнания(безрезультатного ;)). Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 11:47 Код: void send Тут не бой. Тут попытка выкоежиться у BRE. Уже была один раз, но к сожалению он провалил её, убежав с поля боя ;) Получается можно без него обойтись ? странный класс, по-моему программист должен быть просто внимателен и можно обойтись без него Название: Re: Помогите с задачей производителя/потребителя Отправлено: Bepec от Март 03, 2012, 11:53 Я тебе уже привёл пример. Там где вместо 5 строк можно обойтись одной ;)
Это ммм... более удобный класс. Так же, как std::string и QString. Почти одно и то же, но второй удобнее ;) Название: Re: Помогите с задачей производителя/потребителя Отправлено: mutineer от Март 03, 2012, 12:21 Получается можно без него обойтись ? странный класс, по-моему программист должен быть просто внимателен и можно обойтись без него Цена ошибки неразблокировки мьютекса может быть очень высока и отловить ее не всегда легко. Почему бы не использовать этот класс, чтобы снизить вероятность ее возникновения? Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 12:30 Я тебе уже привёл пример. Там где вместо 5 строк можно обойтись одной ;) Это ммм... более удобный класс. Так же, как std::string и QString. Почти одно и то же, но второй удобнее ;) Как заблокировать я понял, просто в конструктор мьютекс передаём, а как при помощи QMutexLocker разблокирует мьютекс? Название: Re: Помогите с задачей производителя/потребителя Отправлено: mutineer от Март 03, 2012, 12:33 Я тебе уже привёл пример. Там где вместо 5 строк можно обойтись одной ;) Это ммм... более удобный класс. Так же, как std::string и QString. Почти одно и то же, но второй удобнее ;) Как заблокировать я понял, просто в конструктор мьютекс передаём, а как при помощи QMutexLocker разблокирует мьютекс? Разблокирует когда уничтожается, то бишь в деструкторе Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 14:04 Я тебе уже привёл пример. Там где вместо 5 строк можно обойтись одной ;) Это ммм... более удобный класс. Так же, как std::string и QString. Почти одно и то же, но второй удобнее ;) Как заблокировать я понял, просто в конструктор мьютекс передаём, а как при помощи QMutexLocker разблокирует мьютекс? Разблокирует когда уничтожается, то бишь в деструкторе Ну тогда мне кое-что не понятно, вот пример что не понятно: Код
Название: Re: Помогите с задачей производителя/потребителя Отправлено: BRE от Март 03, 2012, 14:06 Код
Название: Re: Помогите с задачей производителя/потреб Отправлено: mutineer от Март 03, 2012, 14:08 Ну тогда мне кое-что не понятно, вот пример что не понятно: Код
Локер будет создавать в начале каждой итерации цикла и уничтожаться в конце каждой итерации Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 03, 2012, 14:19 Спасибо конечно, но что у тебя что у Viktor'a одинаково у вас, сообщения отправляет производитель и потребитель мгновенно принимает, ничего никогда не теряется. Неправда, понажимайте кнопку чуть быстрее, Вы увидите что теряютсяP.S. задание чуток изменилось: Если "нельзя класть пока consumer ждет" - то consumer не дождется никогда. Поэтому наверное правильно "producer не должен класть новое сообщение если consumer еще не забрал предыдущее". Тогда attachтеперь надо чтобы сообщение не терялись. поток 1-> по нажатию кнопки создаёт сообщения. кладёт в очередь. И если поток 2 готов принять сообщение, то берёт из очереди и отправляет. поток 2-> ждёт каждые 2 секунды просматривает буфер. Если там чото есть считывает ( то есть этот поток моделирует некое устройство, которое способно только каждые 2 сек считывать). Пока поток 2 ждёт, поток 1 не должен в буфер ничего класть. Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 14:37 Спасибо конечно, но что у тебя что у Viktor'a одинаково у вас, сообщения отправляет производитель и потребитель мгновенно принимает, ничего никогда не теряется. Неправда, понажимайте кнопку чуть быстрее, Вы увидите что теряютсяP.S. задание чуток изменилось: Если "нельзя класть пока consumer ждет" - то consumer не дождется никогда. Поэтому наверное правильно "producer не должен класть новое сообщение если consumer еще не забрал предыдущее". Тогда attachтеперь надо чтобы сообщение не терялись. поток 1-> по нажатию кнопки создаёт сообщения. кладёт в очередь. И если поток 2 готов принять сообщение, то берёт из очереди и отправляет. поток 2-> ждёт каждые 2 секунды просматривает буфер. Если там чото есть считывает ( то есть этот поток моделирует некое устройство, которое способно только каждые 2 сек считывать). Пока поток 2 ждёт, поток 1 не должен в буфер ничего класть. Большое спасибо, теперь это именно то, что нужно, только в буффере не должно быть больше одного символа, надо по 1 символу по нажатию кнопки класть, ну это сам как-нибудь подправлю. Название: Re: Помогите с задачей производителя/потреб&# Отправлено: lolbla2 от Март 03, 2012, 14:40 Ну тогда мне кое-что не понятно, вот пример что не понятно: Код
Локер будет создавать в начале каждой итерации цикла и уничтожаться в конце каждой итерации Хорошо, я скосячил, тогда немного другой пример: Код
локер сдохнет только по окончанию run(), а мне надо после buffer = "xz"; разблочить. Как это сделать? Название: Re: Помогите с задачей производителя/потреб Отправлено: mutineer от Март 03, 2012, 14:42 Либо как сказал BRE, либо не использовать локер, а работать с мьютексом напрямую
Ах да, есть еще самый безумный и невозможный вариант - прочитать-таки доку по QMutexLocker и с удивлением обнаружить там метод unlock() Название: Re: Помогите с задачей производителя/потреб&# Отправлено: Igors от Март 03, 2012, 14:45 Код локер сдохнет только по окончанию run(), а мне надо после buffer = "xz"; разблочить. Как это сделать? Код :) Вообще это называется "scoped" Название: Re: Помогите с задачей производителя/потребителя Отправлено: Igors от Март 03, 2012, 14:47 Большое спасибо, теперь это именно то, что нужно, только в буффере не должно быть больше одного символа, надо по 1 символу по нажатию кнопки класть, ну это сам как-нибудь подправлю. Там константы есть, установите обе в 1Название: Re: Помогите с задачей производителя/потребителя Отправлено: lolbla2 от Март 03, 2012, 14:52 Большое спасибо, теперь это именно то, что нужно, только в буффере не должно быть больше одного символа, надо по 1 символу по нажатию кнопки класть, ну это сам как-нибудь подправлю. Там константы есть, установите обе в 1Спасибо, только максимум в 2 надо было установить, а минимум в 1, а то когда обе 1 прога падала. |