|
Рисование из потока |
|
|
|
Nov 11 2008, 14:18
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 11-11-08
Пользователь №: 41 540

|
Есть устройство, обменивающееся с компьютером по UART. Протокол вида: компьютер запросил - прибор померил и отдал результат. Для компьютера написана программа на Дельфи. Там в потоке принимается результат, и по факту приема выводится на экран в виде графика с помощью компонента TChart. Программа иногда зависает, иногда бывают аксес виалейшен.
Я хочу переписать программу на С, компилятор возьму MSVS C++. Как следует организовывать работу с графикой и ком-портом? Мне видится, что нужно по событию от таймера проверять состояние флага приема информации, и тогда принимающий поток будет передавать точки графика тому, кто будет рисовать на форме... Как я понял, программа часто зависала из-за того, что графика была "тяжелой", и пока что-то рисовалось в поток успевало придти несколько значений и данные терялись... Возможно, там дело обстояло несколько иначе, но мне кажется, что рисовать прямо из потока не очень хорошо. Интересно было бы увидеть как поступают другие в подобных случаях. И еще вопрос по графике. Есть ли что-то типа TChart в C++, уж очень там удобное масштабирование. Читал, что рисование в DC медленное, но может кто-то пробовал его? По сути мне нужно несколько кривых выводить, правда шкала времени (ось Х) довольно длинная, около суток и более, т.е. ничего хитрого. Но с DC придется отказаться от удобностей типа масштабирования.
|
|
|
|
|
 |
Ответов
|
Nov 17 2008, 23:14
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 11-11-08
Пользователь №: 41 540

|
Цитата Воспользоваться synchronized процедурой Ага, теперь понял откуда ноги ростут. Эта процедура из TThread. При создании модуля с классом TThread и написано, что нельзя рисовать из потока, кроме как используя метод synchronize. Позже попробую написать его потомок, а пока я потоки реализованы с помощью API. В этом случае есть возможность рисовать из потока в главном окне? Цитата Нужно и то и другое - с помощью event'ов сообщать что появились новые данные, с помощью CriticalSection защищать доступ к этим данным (FIFO) из 2х разных потоков Что бы не действовать методом научного тыка приведу краткий алгоритм, а то не уверен, что правильно Вас понял. Поток приема из УАРТа. Код 1. Ждем стартовый байт. (WaitCommEvent(), WaitForSingleObject()) 2. Входим в критическую секцию. (EnterCriticalSection()) 3. Записываем данные в буфер. (ReadFile()) 4. Выходим из критической секции. (LeaveCriticalSection()) 5. Устанавливаем событие в сигнальное состояние (событие с автосбросом) (SetEvent()) 6. Переходим к п. 1. Поток обработки данных Код 1. Ждем наступления события. (WaitForSingleObject()) 2. Входим в критическую секцию. 3. Извлекаем данные из буфера. 5. Выходим из критической секции. 6. Переходим к п. 1. И как после извлечении данных из буфера и выхода из критической секции вставить пункт "Рисуем в главном окне", чтобы он отработал нормально?
|
|
|
|
|
Nov 18 2008, 06:45
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(hadrov @ Nov 18 2008, 02:14)  Ага, теперь понял откуда ноги ростут. Эта процедура из TThread. При создании модуля с классом TThread и написано, что нельзя рисовать из потока, кроме как используя метод synchronize. Позже попробую написать его потомок, а пока я потоки реализованы с помощью API. В этом случае есть возможность рисовать из потока в главном окне? Что бы не действовать методом научного тыка приведу краткий алгоритм, а то не уверен, что правильно Вас понял. Поток приема из УАРТа. Код 1. Ждем стартовый байт. (WaitCommEvent(), WaitForSingleObject()) 2. Входим в критическую секцию. (EnterCriticalSection()) 3. Записываем данные в буфер. (ReadFile()) 4. Выходим из критической секции. (LeaveCriticalSection()) 5. Устанавливаем событие в сигнальное состояние (событие с автосбросом) (SetEvent()) 6. Переходим к п. 1. Поток обработки данных Код 1. Ждем наступления события. (WaitForSingleObject()) 2. Входим в критическую секцию. 3. Извлекаем данные из буфера. 5. Выходим из критической секции. 6. Переходим к п. 1. Да, именно так Цитата И как после извлечении данных из буфера и выхода из критической секции вставить пункт "Рисуем в главном окне", чтобы он отработал нормально? Посадить потоки на TThread, или вручную реализовать то, что сделано в TThread::Synchorize. А именно - - Данные помещаются в очередь (можно просто переменная)
- Главному окну посылается специальное сообщение (любое)
- WaitForSingleObject(sync_event)
В обработчике специального сообщения главного окна: - Забираем данные, рисуем
- SetEvent(sync_event)
Event sync_event должен быть создан как Код sync_event=CreateEvent(NULL,FALSE,FALSE,NULL);
|
|
|
|
Сообщений в этой теме
hadrov Рисование из потока Nov 11 2008, 14:18 DpInRock В Си ошибок только прибавится. Причем, на порядок.... Nov 11 2008, 15:14 SysRq В Borland C++ Builder есть TChart.
Еще вариант ви... Nov 11 2008, 19:45 hadrov ЦитатаВ Си ошибок только прибавится. Причем, на по... Nov 12 2008, 08:37 XVR Цитата(hadrov @ Nov 12 2008, 11:37) Прогр... Nov 12 2008, 11:31 Demeny Цитата(hadrov @ Nov 11 2008, 17:18) Как с... Nov 12 2008, 10:04 SysRq Может стоит перейти на .NET? Оно относительно один... Nov 12 2008, 10:36 hadrov С учетом того, что потребуется версия для КПК, то,... Nov 12 2008, 10:46 Kopa Цитата(hadrov @ Nov 12 2008, 13:46) С уче... Nov 12 2008, 12:13 hadrov Цитатанеобходим хотя бы небольшой буфер под приним... Nov 12 2008, 11:55 XVR Цитата(hadrov @ Nov 12 2008, 14:55) Вы им... Nov 13 2008, 07:47  CSB ... Nov 17 2008, 23:00 defunct Цитата(hadrov @ Nov 12 2008, 13:55) Вот г... Dec 23 2008, 02:09 hadrov С Си знаком лучше всего.
И я не знаю как быстро ра... Nov 12 2008, 13:30 Олег Хохлов Цитата(hadrov @ Nov 11 2008, 16:18) Есть ... Nov 12 2008, 18:44 AHTOXA Цитата(hadrov @ Nov 18 2008, 04:14) Поток... Nov 18 2008, 07:40  XVR Цитата(AHTOXA @ Nov 18 2008, 10:40) Не та... Nov 18 2008, 09:25   AHTOXA Цитата(XVR @ Nov 18 2008, 14:25) Частые з... Nov 18 2008, 09:46 hadrov Цитата(AHTOXA @ Nov 18 2008, 13:46) Ну а ... Nov 18 2008, 10:32 AHTOXA Цитата(hadrov @ Nov 18 2008, 15:32) Я сей... Nov 18 2008, 11:03 hadrov ЦитатаНет, так нельзя.Теперь ясно. Я не так понял ... Nov 18 2008, 11:20
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|