![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| wallstreet |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Ну так еще бы, проект сырой очень, да и вообще) На самом деле постоянно что-то меняю что-то пробую, поэтому и переменных куча ненужных. Вобщем впреть постараюсь сразу удалять. Хорошее замечание!
Да, точно. Теперь матрица заполняется правильно, но неправильными числами. (сейчас я изменил заполнение на рендомное) А с чем конкретно в итераторах? Я неправильно с ними работаю? Пробовал в консоле данную структуру создания и вывода, все работало как часы. 1/ ОК. Убрал секцию cs, только теперь смущает, что первый поток, который по идее должен был заниматься выделением памяти под данные, не занимается ничем. Ну да ладно.. 2/ сsX - защищает модификацию и чтение вектора 3/
Если я инициализирую значения сх и су в потоке3, в секции csShared то растр не отрисовывается в WM_PAINT.
Значение переменной ::scrlh изменяет локальная переменная scrlh диалога1 на значение выбранное скроллбаром в обработке нажатия кнопки "ОК". Собственно оную нажав мы и изменяем исходные параметры размерности моего вектора и растра. Т.е. мы открыли диалог1, выбрали размерность матрицы, нажали "ОК" и матрица должна сразу же поменять размер и перерисоваться на главном окне. Именно поэтому, как мне казалось, правильнее было прилепить запуск потоков к обрабоке нажатия кнопки ОК, что я и делал, но вопрос с Таймером для меня был открыт. Вобщем, если с потоками все понятно, то как изменить значение переменной ::scrlh в потоке2, для меня загадка?!?! В принципе можно создать еще одну переменную, локальную для потока2 и брать значение глобальной ::scrlh, но есть ли в этом смысл? 4/ Честно признаться не помню уже какую цель преследовал, но явно над чем-то эксперементировал методом тыка) 5/ Таймер будет скоро. Если не сложно, подскажите как я могу его запускать из диалога1 и где его устанавливать, т.к. он запускает потоки, а они у меня запускаются при создании окна и второй раз их запускать таймером будет неправильно. 6/ Ну основную логику описал в п. 3. Просто думал так, что запуск потоков с созданием и отрисовкой матрицы необходимо делать после того как пользователь определится с ее размером, а самым лучшим для этого подтверждением является нажатие на кнопку "ОК". Сейчас то, с вашей помощью, я уже понял как можно по другому (страшно сказать правильно 7/ Удалил ненужные, а вот hMemBitmap очень даже нужная. Это наш растр, который мы создаем в потоке2, а в потке3 инициализируем им hMemSharedBitmap. Однако в глобале ей делать нечего и это факт) 8/ Ну моя цель работы над данным проектом это учеба. С сбытиями разобрался, теперь представилась возможность попрактиковаться с семафорами. Почему бы и нет Ссылка на проект тут -> обновленный вариант Это сообщение отредактировал(а) wallstreet - 10.4.2012, 10:09 |
||||||||
|
|||||||||
| wallstreet |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Вот я прописал таймер.
Он у меня создается в момент создания окна. Создается без задержек и сразу же запускает потоки, но потоки не отрисовывают раст, т.к. семафорХ не запущен. Этот семафор освободит диалог1 после того как пользователь определится с размерностью матрицы, которую хочет видеть на экране и нажмет кнопку "ОК". Предположим пользователь сидит и смотрит на пустое окно и размерность массива не выбирает, даже диалог1 не открывает. Так вот мне интересно, в этот момент мой таймер что делает, создает раз в секунду поток, который ожидает освобождения семафораХ? Так вот вопросы эти появляются только потому, что после того как я определю размерность матрицы в диалоге1 программа отрисует один раз мой растр и все. Да еще и непонятно почему заполняет только матрицу 10х10 правильно, а при заполнении 5х5, к примеру, то будет она выглядеть вот так: ![]() хотя должен был начинаться второй ряд с 5 6 7 8 9, ну и тд. И что самое главное картинка не перерисовывается с новой матрицей, хотя вроде и цикл есть в потоках, но не хочет. Почему?( Ссылка на проект тут=>проект Заранее благодарю за ответы! Это сообщение отредактировал(а) wallstreet - 11.4.2012, 17:45 |
|||
|
||||
| GremlinProg |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
таймер должен заменить семафорХ, а не дополнить, просто удали семафорХ, диалог теперь не должен запускать поток, т.к. он запускается таймером, но возникает еще один конфликт, подобный hSharedBitmap: переменная scrlh в таком случае тоже должна быть защищена из диалога и в потоках теперь по коду: 1. у тебя опять путаница в ролях потоков: зачем первый поток очищает массив, когда он должен задавать его размер? 2. ладно, очищает, но почему без синхронизации? 3. "ЗАПОЛНЕНИЕ ВЕКТОРА" ну сам же пишешь: "ЗАПОЛНЕНИЕ", т.е. заполнение его данными, а почему я вижу в цикле push_back? второй поток не должен вызывать ни каких операций, связанных с изменением размеров вектора, этим должен заниматься первый поток, соответственно, раз cx и cy напрямую зависят от scrlh, второй поток тоже не должен трогать эти переменные, оставь и эту работу первому потоку не создает, а пробуждает, или запускает, на счет семафораХ уже сказал, на данный момент его должен заменить таймер в принципе, задача так и стоит: по таймеру пускать всю цепочку событий, пользователю, конечно это может не так интересно наблюдать, я бы мог предложить более интересный вариант: заполнять массив не тупо значением j++, а добавить сюда элемент уникальности, например factor * j++, тогда factor будет один раз инициализироваться перед заполнением массива, например так:
тогда всякий раз, после запуска цепочки, картинка будет меняться, пользователю будет не так скучно, ну, или можно вообще отвязать изменение factor от потоков, а менять его значение в диалоге, вручную
ну, это потому, что у тебя тут стоит TRUE:
а должно быть как минимум FALSE, ну а как оптимум: hSemaphoreX тут быть не должно, хотя, если бы задача стояла: пускать первый поток либо по таймеру, либо по активности пользователя, то можно было бы и оставить, это интересная практика, да и пользователю хорошо: изменения сразу вступают в силу, после закрытия диалога
а что не нравится? тут все верно:
это означает, что для 10x10 значения массива будут выведены в 10-чной системе счисления, для 5x5 - в 5-чной и т.д. если надо все выводить в 10-чной, передавай в последний параметр 10, а не vv.size() -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||||
|
|||||||||||
| feodorv |
|
||||||||||||||||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Здесь я не совсем согласен Изначально Event0 нужен был только для того, чтобы пробудить Thread1 не дожидаясь срабатывания таймера (то есть для корректного завершения программы). В сущности, для этого же нужен SemaphoreX, ни больше ни меньше. То есть он нужен (если им правильно пользоваться):
Конечно, так не годится. Ожидается и таймер и семафор одновременно. Зачем? Почему не так:
Ээээ... Увидел
Опять же, не совсем согласен cx и cy используются в отрисовке битмапа:
Менять отдельно cx, cy и hMemSharedBitmap не стоит!!! Иначе говоря cx и cy нужно менять в Thread3 в момент
То есть:
Тут же встают проблемы инициализации и очистки
Если хочется всё стартовать через Dialog1, то можно сделать так:
Соответственно в Dialog1:
Соответственно в WndProc убрать код инициализации hTimer, ThreadXXX и
Можно launchDialog вызвать и в момент окончания инициализации главного окна (принудить пользователя к действиям), но это особая история...
Во-первых, vv.clear() стоит делать только после завершения всех потоков. Во-вторых, потоки нужно предварительно пробудить. В-третьих
это лишнее, а вот hMemSharedBitmap освободить нужно!!! В четвёртых, надо освободить таймер. В пятых, перед ожидаем потоков, стоит проверить, что они вообще были запущены. То же к таймеру и семафорам. Да я не в притензии, я для дела сугубо))) Это сообщение отредактировал(а) feodorv - 12.4.2012, 18:18 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Event0 - это семафорХ? если так, то изначально этот семафор пускал первый поток, о завершении потоков мы как-то уже договорились, что пока на нем заморачиваться не будем, потом, для завершения всех потоков лучше сделать одно событие hAbort, которое и заменит флаг done если не опираться на cx и cy в 3-м потоке, при создании растра, то да, так будет безопасно для основного потока, хотя он может получить эту же информацию из растра, через GetObject, на счет безопасности в основном потоке я бы как раз пока особо не переживал, я сейчас говорю об инициализации растра в 3-м потоке, теоретически, раз от размера вектора зависит размер растра, и размер вектора выставляется в критической секции x, то разумно было бы и размер растра выставлять/получать в этом критическом участе кода, тогда нет разницы, в каком потоке это будет сделано -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| wallstreet |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Всем спасибо за помощь.
кое что подправил, завтра думаю добью если время будет. Ссылка на проект =>проект |
|||
|
||||
| feodorv |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
GremlinProg
Конечно, при отрисовке битмапа неверные cx и cy не скажутся на безопасности выполнения основного потока, но дело в принципе:
Между Thread1 и Thread3 может случится WM_PAINT. При этом hMemSharedBitmap ещё старая, а значения cx и cy уже новые, не когерентные с hMemSharedBitmap...
Вот это было бы лучше всего (чтобы не было путаницы), а от cx и cy можно будет отказаться вообще...
Прошу прощения, но эта мысль никак не желает достигнуть нужных отделов моего слабеющего мозга))) wallstreet
В смысле??? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||
|
|||||||||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
равно как и между Thread3 и WM_PAINT может случиться Thread1 и Thread2 reserve не задает размер вектора, здесь нужен resize
либо отказаться, либо завести еще пару, ибо под одним синхронизатором кто-нибудь обязательно будет в пролете: либо растр, либо WM_PAINT
судя по коду, она все же нашла, что искала -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| wallstreet |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Ну, полностью отказаться я не знаю как, т.к. при создании растра hMemBitmap, в третьем потоке, мы задаем его размеры.
В этот момент еще нет хендла растра из которого можем вытащить высоту и ширину. Т.о. я оставил инициализацию cx и cy в первом потоке исключительно для создания первого растра hMemBitmap. В то время как для отрисовки в WM_PAINT я ширину и высоту вытаскиваю из уже готового растра hMemSharedBitmap, которому до этого присваиваю hMemBitmap. Если вы покажете способ избавиться от сх и су полностью, буду признателен.
Видимо я неполноценно выразил свою мысль, но если вы попробуете размер матрицы установить, предположим, в 10х10 с помощью скроллбара, а затем второй раз, уже рисующийся растр изменить на размер 5х5 с помощью все того же скроллбара, то заметите как он где-то на секунду приостановит отрисовку и потом уже нарисует правильный размер матрицы, а при увеличении размера, такой задержки не последует. Так вот меня интересовали причины по которым отрисовка подтормаживается при уменьшении размера растра. Собственно на выше приведенный участок кода я и стал грешить, хотя может зря, может причина в другом? ссылка на проект:скачать проект |
||||||||
|
|||||||||
| GremlinProg |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
это равнозначно такому коду:
т.е. таким кодом ты дважды меняешь размер вектора, причем в конечном счете он оказывается пустым зачем тебе это понадобилось, я пока не вникал, но если это и есть твоя операция по изменению размера вектора, то любое обращение к его элементам после этого должно генерировать ошибку -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
| GremlinProg |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
упс, недопонял я этот код привел для WM_PAINT'а, т.е. не для 3-го, а для основного потока -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
| wallstreet |
|
||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
да да да, именно так я и вытаскиваю высоту и ширину из hSharedBitmap в WM_PAINT, но не использовать сx и cy в третьем потоке не знаю как. Хотя по большому счету если не запустится поток2, то не запустится и поток3, а второй запускается только после того как зпускается поток1 в котором инициализируются сx и су. Так что между потоками нестыковок в работе не должно быть, а в WndProc при отрисовке берется высота и ширина из битмапа, так что думаю все ок тут с синхронизацией.
Я понимаю так. Поток1 ресайзит вектор. Предположим, что он уже заполнен значениями 1, 2, 3, 4, 5. Так вот если я изменяю его размер вот так:
то получу в результате: 1, 2, 3, 4, 5, NULL, NULL, NULL и если я в дальнейшем не удалю значения оставив только размерность, то используя push_back() во втором потоке, значения вставятся непонятно как для меня. Т.е. если убрать удаление элементов вектора из потока1, то WM_PAINT отрисовывает черный квадрат заданой размерности, без чисел. Изначально думал резервировать память под вектор, если его размер 0, в потоке1 функцией reserve(), а в потоке2 заполнять исходя из его capacity() простым циклом. Если же вектор.size() > 0 тогда изменять его размер функцией resize(), но как проблему решить с очисткой от значений я не знал поэтому все на выходе получалось через стерни к звездам. Добавлено через 14 минут и 11 секунд вообще думал сделать изменение размера вектора и его заполнение как-то так: Поток1
Поток2
Но этот код не работает, матрица отрисовывается один раз и вылазит ошибка Debug Assertion Failed! Expression: vector iterators incompatible |
||||||||||
|
|||||||||||
| GremlinProg |
|
||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну смотри, в первом потоке задаешь размер массива:
а во втором его заполняешь:
если проблем с синхронизацией нет, значит ошибок тут тоже не будет, и не важно, какой размер был на предыдущей итерации, черный квадрат у тебя точно не из-за того, что сохраняются старые значения в массиве -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||||
|
|||||||||||
| wallstreet |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
эээ.. стесняюсь спросить auto это что? насколько я понимаю it это итератор, но чем он отличается от std::vector<std::vector<int>>::iterator it? Это сообщение отредактировал(а) wallstreet - 18.4.2012, 13:53 |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ни чем не отличается -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |