Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.02.2013, 06:00   #1
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию Запутался с потоками.

Код:
void __stdcall MyIFCallback(CONST SHORT *Buffer,UINT32 NumberOfSamples,WORD MaxADCAmplitude,UINT32 ADCSamplingRate,DWORD_PTR UserData)
{
        FormMain->Series1->Clear();
        while (NumberOfSmples--)
        {
                FormMain->Series1->AddY(Buffer[NumberOfSmples]);
        }
        return;
/*
*Buffer-массив данных;
NumberOfSamples-число данных в буфере (65536);
MaxADCAmplitude-максмимальное значение из буфера;
ADCSamplingRate-частота дискретизации;
UserData-пользовательские данные;
*/
};
Вызывыется эта функция с помощью StartIF(INT32 hDevice,WORD Period), где Period время отправки (в мс) массива данных в ф-ю MyIFCallback. Мне нужно построить график этого массива, если воспользоваться кодом который я привел выше то выводит ошибка "Access violation at address XXXXXXXX. Read of address YYYYYYYY" (если задать рисовать не все элементы, а например 650, то все работает, но не долго). Ф-я StartIF(INT32 hDevice,WORD Period) создает свой поток и насколько я понял, ошибка получается из-за рассинхронной работы потоков StartIF и FormMain. Как синхронизировать потоки? Или может есть какие-то другие способа решения проблемы?
qwertyk вне форума Ответить с цитированием
Старый 01.02.2013, 10:02   #2
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Покажи FormMain->Series1->AddY
FataLL вне форума Ответить с цитированием
Старый 01.02.2013, 12:57   #3
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Покажи FormMain->Series1->AddY
Всмысле показать? Series1 относится к TChart.
qwertyk вне форума Ответить с цитированием
Старый 01.02.2013, 15:58   #4
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Попробуй сформируй отдельную серию, а потом FormMain->Series1->AssignValues. Кстати, это ничего, что данные в обратном порядке добавляются?
FataLL вне форума Ответить с цитированием
Старый 01.02.2013, 22:02   #5
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Попробуй сформируй отдельную серию, а потом FormMain->Series1->AssignValues.
Дело не в этом. Это проблема синхронизации потоков.
Цитата:
G31DDC_CALLBACKS

Contains pointers to user-defined functions to be registered as callback functions.

Each callback function is called in context of thread created by the API. If some shared data are accessed inside callback functions, it is recommended to use a mutual-exclusion synchronization method. The application should not call any G31DDC API function from inside callback functions, otherwise it can cause deadlock or the application can become to unpredictable state.
qwertyk вне форума Ответить с цитированием
Старый 02.02.2013, 18:11   #6
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Код:
double *dblIFCallbackBuff;//массив содержит значения *Buffer из MyIFCallback
CRITICAL_SECTION csIFCallback;
HANDLE hEventIFCallback;
HANDLE hThreadDrawIFCallBack;
DWORD idThreadDrawIFCallBack;
.......................................
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
        hEventIFCallback=CreateEvent(0,1,1,0);//изначально устанавливаем сигнальное состояние
 
        InitializeCriticalSection(&csIFCallback);
        dblIFCallbackBuff=new double[65536];
.......................................
}
DWORD WINAPI ThreadDrawSpectrumADC(LPVOID param)//поток для рисования спектра
{
        EnterCriticalSection(&csIFCallback);
 
        FormMain->Series1->Clear();
        for (UINT i=0;i<65536;++i) FormMain->Series1->AddY(dblIFCallbackBuff[i]);
 
        LeaveCriticalSection(&csIFCallback);
 
        SetEvent(hEventIFCallback);
 
}
 
void __stdcall MyIFCallback(CONST SHORT *Buffer,UINT32 NumberOfSamples,WORD MaxADCAmplitude,UINT32 ADCSamplingRate,DWORD_PTR UserData)
{
        WaitForSingleObject(hEventIFCallback, INFINITE);
 
        EnterCriticalSection(&csIFCallback);
 
        for (UINT i=0;i<NumberOfSamples;++i) dblIFCallbackBuff[i]=Buffer[i];//copy *Buffer
 
        LeaveCriticalSection(&csIFCallback);
 
        hThreadDrawIFCallBack=CreateThread(0,0,&ThreadDrawSpectrumADC,0,0,&idThreadDrawIFCallBack);//создаем поток
 
        ResetEvent(hEventIFCallback);//переводим в сигнальное состояние, когда поток ThreadDrawSpectrumADC выполнится он вернет сигнальное состояние
 
        WaitForSingleObject(hEventIFCallback, INFINITE);//ожидаем пока поток ThreadDrawSpectrumADC выполниться
        
        CloseHandle(hThreadDrawIFCallBack);
        return;
};
Выдает ошибку которую описал в первом посте. Что не так или как исправить?
qwertyk вне форума Ответить с цитированием
Старый 04.02.2013, 10:12   #7
FataLL
Форумчанин
 
Аватар для FataLL
 
Регистрация: 29.01.2013
Сообщений: 319
По умолчанию

Подобавляй в серию какие-либо случайные значения, не из массива (можно random). Уйдёт ошибка или нет? И, кстати, NumberOfSamples не всегда равняется 65536?
FataLL вне форума Ответить с цитированием
Старый 04.02.2013, 16:12   #8
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Цитата:
Сообщение от FataLL Посмотреть сообщение
Подобавляй в серию какие-либо случайные значения, не из массива (можно random). Уйдёт ошибка или нет? И, кстати, NumberOfSamples не всегда равняется 65536?
Если вообще не использовать функцию MyIFCallback, т.е. рисовать свой рандомный массив, то все нормально. Если же я буду рандомный массив создавать в ф-ии MyIFCallback, то появляется ошибка. Я выше описал, что ф-я Callback создает свой поток, но как его синхронизировать с потоком формы? NumberOfSamples всегда равняется 65536.(Кстати, если буду рисовать не весь массив, а например только 2000 значений, то график рисуется, но через некоторое время появляется ошибка.)
qwertyk вне форума Ответить с цитированием
Старый 04.02.2013, 23:05   #9
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Код:
 
CRITICAL_SECTION g_csIFCallback;
double_dynarr g_dynarrIFCallbackBuff(0);//динамический массив (сам написал класс)
 
 
void __stdcall MyIFCallback(CONST SHORT *Buffer,UINT32 NumberOfSamples,WORD MaxADCAmplitude,UINT32 ADCSamplingRate,DWORD_PTR UserData)
{
        EnterCriticalSection(&g_csIFCallback);
   
        for (UINT i=0;i<NumberOfSamples;++i) g_dynarrIFCallbackBuff[i]=Buffer[i];//копируем значения в глобальный динамический массив
 
        LeaveCriticalSection(&g_csIFCallback);
 
        return;
};
void __fastcall TFormMain::Timer1Timer(TObject *Sender)
{
        FormMain->Series1->Clear();
        FormMain->Series1->AddArray(&g_dynarrIFCallbackBuff[0],65536);//рисуем
 
        Timer1->Enabled=true;
        return;
}
Вот этот код работает(т.е. через определенные интервалы мы рисуем массив). Меня все равно интересует почему если создать отдельный поток для рисования массива то вылазиет ошибка?
qwertyk вне форума Ответить с цитированием
Старый 05.02.2013, 10:10   #10
qwertyk
Пользователь
 
Регистрация: 15.07.2009
Сообщений: 52
По умолчанию

Сам нашел ответ на свой вопрос. Обращаться к vcl из вторичного потока (ф-я ThreadDrawSpectrumADC()) нельзя, vcl на такое не рассчитана. Для поддержки потоков есть TThread...
qwertyk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Запутался в написании. tesma Паскаль, Turbo Pascal, PascalABC.NET 4 25.02.2012 13:39
Запутался с меню nikolj HTML и CSS 2 27.11.2011 18:44
Запутался с формами iHikita Общие вопросы .NET 6 30.07.2010 16:08
запутался! mistertvister Помощь студентам 3 28.10.2009 14:52
запутался в процедурах world12_tk Помощь студентам 6 03.03.2009 18:57