Re[9]: Проблема с потоками
От: Carc Россия https://vk.com/gosha_mazov
Дата: 15.07.14 23:01
Оценка: +1
К>Вообще-то, MFC-шная отправка сообщения и голая WINAPI-шная мало чем отличаются.
К>Просто поменяем шило на мыло.
Еще как отличаются...
Aml Pages Home
Re[10]: Проблема с потоками
От: Кодт Россия  
Дата: 16.07.14 10:47
Оценка:
Здравствуйте, Carc, Вы писали:

К>>Вообще-то, MFC-шная отправка сообщения и голая WINAPI-шная мало чем отличаются.

К>>Просто поменяем шило на мыло.
C>Еще как отличаются...

И в чём отличия, кроме увеличения числа граблей (большее количество объектов, в которые можно выстрелить)?
Перекуём баги на фичи!
Re[11]: Проблема с потоками
От: Carc Россия https://vk.com/gosha_mazov
Дата: 16.07.14 11:04
Оценка:
К>>>Вообще-то, MFC-шная отправка сообщения и голая WINAPI-шная мало чем отличаются.
К>>>Просто поменяем шило на мыло.
C>>Еще как отличаются...

К>И в чём отличия, кроме увеличения числа граблей (большее количество объектов, в которые можно выстрелить)?

MFC как-то очень не любит, когда из соседнего потока пытаются обратиться к CWnd адресуемого картой объектов из гуевого потока. А оно нам надо? Не проще ли передать в рабочий поток параметром до кучки и HWND? И слать сообщение через чистый API. Там — чисто теоретически конечно — можно хотя бы проверить валидность HWND через IsWindow. А с указателем что делать? Есть конечно варианты, IsBadReadPtr — но по уму он выдаст только доступность чтения памяти, а что там в ней мало понятно.

Второе: проблема там в другом. Дело в том, что рабочий поток сам балуется SetStatusText. Т.е. она выполняется в контексте рабочего потока. И соответственно который может быть прерван где-то посередине, и дальше гуевый потом сам начнеть баловать с SetStatusText. По идее если поковыряться, то вроде как там все равно все сведется к отсылке сообщение и можно вроде и забить. Но это все грабли. Не проще ли отослать фрейму сообщение с данными, а он уже разгребая очередь сам обновит данные в строке.

Остальное все нюансы и преждевременные причем. Можно и готовую строку передавать в отсылке сообщения, а формировать строку для статусбара в рабочем потоке. Можно только данные гонять через сообщение (я так понимаю там просто какие числа, которые мы может легко передать как копии через WPARAM\LPARAM). Можно все это синхронно, можно асинхронно. По всякому можно. Но это детали. На 99 из 100 уверен, что проблема в попытке рабочего потока манипулировать напрямую контролами гуевого потока. Плохая практика. Достаточно сказать гуевому потоку, мол измени, а он сам разрулит.
Aml Pages Home
Re[12]: Проблема с потоками
От: Кодт Россия  
Дата: 16.07.14 12:55
Оценка: 1 (1)
Здравствуйте, Carc, Вы писали:

C>Не проще ли отослать фрейму сообщение с данными, а он уже разгребая очередь сам обновит данные в строке.


И тут сразу встанет вопрос о сериализации этих данных.

C>Достаточно сказать гуевому потоку, мол измени, а он сам разрулит.


Об том и речь. Пусть гуёвый поток умеет читать и публиковать данные в любой момент времени, а рабочий только сообщает, что пришла пора обновиться.
Перекуём баги на фичи!
Re[13]: Проблема с потоками
От: Carc Россия https://vk.com/gosha_mazov
Дата: 16.07.14 13:06
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Carc, Вы писали:


C>>Не проще ли отослать фрейму сообщение с данными, а он уже разгребая очередь сам обновит данные в строке.


К>И тут сразу встанет вопрос о сериализации этих данных.

Да ну, какой там вопрос? Вариантов то немного: SendMesage(...., (LPARAM)указатель_на_данные_на_стеке), или PostMessage/PostThreadMessageSendMesage(...., (LPARAM)new (наши_данные)), а гуевый поток уж освободит память. Понятно есть нюансы, может там число и никакие new не нужны, может вообще есть какой-то слева пул\очередь данных Но это уже специфика конкретной задачи и только.

C>>Достаточно сказать гуевому потоку, мол измени, а он сам разрулит.


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

Дык я про то топикстартеру и толковал. Не нужно мутить критические секции только из-за этого. Рабочий поток чего-то обновил (вот тут вот может и под критической секцией — только толку от нее тут), и дернул гуевый. Гуевый сам все отвизуализирует. Ему по любому лучше знать как и когда отвизуализироваться (ну мало ли там, может быть на 100-ом элементе потом понадобится MessageBox показывать, "Давай бабла, триал закончен" или что-то вроде возможности отменить длительный процесс).
Aml Pages Home
Re[14]: Проблема с потоками
От: Кодт Россия  
Дата: 16.07.14 14:49
Оценка: 1 (1)
Здравствуйте, Carc, Вы писали:

К>>И тут сразу встанет вопрос о сериализации этих данных.

C>Да ну, какой там вопрос? Вариантов то немного: SendMesage(...., (LPARAM)указатель_на_данные_на_стеке),

Разложить грабли для дедлока, я уже написал об этом

C>или PostMessage/PostThreadMessageSendMesage(...., (LPARAM)new (наши_данные)), а гуевый поток уж освободит память.


Ходьба по канату.
Не знаю, как у других, а я давно уже понял, что отдавать владеющие указатели в свободное плавание по виндовской очереди сообщений — рискованно.
Ибо придётся заботиться о гарантированной доставке, и программа становится слишком плотно связанной.
Перекуём баги на фичи!
Re[9]: Проблема с потоками
От: WiseAlex Беларусь  
Дата: 19.07.14 22:10
Оценка:
Здравствуйте, Кодт, Вы писали:
К>Акт первый. "Наивность".
К>Из рабочего потока посылаем WM_SETTEXT (ну или SetStatusText, который в итоге сведётся к WM_SETTEXT).
К>Оконный поток об этом не подозревает, параллельно тоже что-то там своё делает, — классическая гонка.
К>Особенно, если SetStatusText выполняет какую-то ещё полезную работу, кэширует строку, например.

Можешь пояснить, если не сложно?
Всегда думал, что оконный поток обрабытавает все сообщения последовательно, получая их из очереди сообщений.
MSDN: Messages sent between threads are processed only when the receiving thread executes message retrieval code.
Как может здесь получится гонка в оконном потоке?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.