Проблемы синхронизации

Обсуждения по программированию для ОС Windows безотносительно используемого языка программирования. Windows NT, Win32, Windows API, ядро и драйверы.
SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Проблемы синхронизации

Сообщение SLIM » 05.03.2011 (Сб) 0:47

Как всегда замылился взгляд, прошу помощи. (Visual C++ 2010)

Есть Win32 приложение, создается окно с WinPorc и т.д. Все стандартно.
Есть некий массив структур, на основании которых обновляется ListView в окне. Вызов функции - обновить инфу. Обновление вынесено в отдельную функцию.
В этом же неком массиве структур есть указатель на эту самую функцию обновления. Таким образом, вызвав эту функцию из любого элемента массива структур - обновится информация по данному элементу.
Вот прототип ф-ии
Код: Выделить всё
typedef void (__stdcall *updteinfo) (void*, int, LPTSTR);

В структуре поле объявляется так
Код: Выделить всё
updteinfo FnUpdate;


Далее. Есть библиотека, в которую передается указатель на массив данных структур. В данной библиотеке есть функция, которая вызывается из основного приложения. Эта функция создает поток бесконечно зацикленный, который юзает массив структур. В этом же потоке может создавать еще несколько потоков и т.д. В любом из потоков может быть множество вызовов функции по указателю в структуре, которая обновляет все тот же ListView.

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

Но! Тут проблема.

После завершения потока в библе (всех потоков), остались...как бы это сказать. В общем поток закончен, а ListView еще обновляется. Т.е. мы ожидаем что после завершения всех потоков в listview будут символы @, а на самом деле туда попадает какое-то последнее обновление.

Получается, что какие-то сообщения не обработал поток основной программы а не библиотечной. Это не очень хорошо, так как в ListView у нас появляется мусор, который уже не актуален.

Неправильная архитектура? Но я и не думал что что-то может доходить с запозданием до главного окна.
Что в общем сделать бы?

З.Ы. Надеюсь понятно объяснил :)
Пишите жизнь на чистовик.....переписать не удастся.....

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3979
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Проблемы синхронизации

Сообщение BV » 05.03.2011 (Сб) 15:52

Не очень понятно. Точнее, я вообще ничего не понял по поводу связи обработки в основном потоке и в библиотечных потоках. Они как-то засинхронизированы? Там используется GetMessage/PeekMessage PM_REMOVE?
char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: Проблемы синхронизации

Сообщение SLIM » 05.03.2011 (Сб) 23:00

BV писал(а):Не очень понятно. Точнее, я вообще ничего не понял по поводу связи обработки в основном потоке и в библиотечных потоках. Они как-то засинхронизированы? Там используется GetMessage/PeekMessage PM_REMOVE?

В основной программе дополнительно созданных потоков нет. Все потоки в библе.
В свою очередь, потоки (в библе) вызывают ф-ю в структуре, которая шлет сообщения окну программы. Так вот после того, как поток (из библиотеки), который послал сообщение основному окну программы уже уничтожен, сообщение основной программы еще не обработано.

Я синхронизировал все потоки библиотеки, но это никак не связано с основным потоком приложения.
Происходит примерно следующее
1. Из основной программы вызывается ф-я библы, которая создает поток.
2. В этом потоке - бесконечно крутящийся цикл. Цикл прерывается при выставлении флага в глобальной переменной (она проверяется на каждом шаге в бесконечном цикле потока)
3. Во время работы потока в библе, который был создан еще в п.1 шлется куча сообщений основному окну. Шлется быстро и много - на каждой итерации.
4. Чтобы остановить такой поток нужно выставить флаг. Поэтому в библе есть ф-я, которая выставляет флаги так, чтобы поток приостановился. Эта функция выставляет флаг и ждет когда поток прекратит свою работу.
5. После остановки потока посредством флага из указанной в п.4 функции (которая в библе), основному окну шлется опять сообщение разово.
6. !!!! Когда в п.5 сообщение было послано, оно обрабатывается. Например в ListView появляется какое-то значение. Оно появляется и тут же меняется на другое. Это другое - это сообщение, которое послал завершающийся в п.4 поток. Оно каким-то образом оказалось после сообщений из п.5. В итоге имеем некорректную информацию.

Так вроде должно быть понятно. Это упрощенный вариант. На самом деле там вместо флага стоит событие, в бесконечном цикле может создаваться еще несколько потоков (а может и не создаваться), которые потом тоже ожидаются. Ну короче там все посложнее. Но суть одна.


UPD:: Да, по поводу PeekMessage я пробовал, но здесь проблема в другом, потому это не необхоимость. Можно правда попробовать организовать очередь сообщений потока, но это тоже вроде не требуется.
Пишите жизнь на чистовик.....переписать не удастся.....


Вернуться в Windows-программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

    TopList