Визуальное моделирование сложных реагирующих систем при помощи диаграмм состояния UML Harel - Приложения и примеры
ОГЛАВЛЕНИЕ
Страница 6 из 6
Приложения и примеры
Допустим, что есть два экземпляра конечного автомата Player1 и Player2, выполняющиеся в двух потоках, и контексты этих потоков - AppThreadContext1 и AppThreadContext2.
CPlayer Player1;
CPlayer Player2;
SME_THREAD_CONTEXT_T g_AppThreadContext1;
SME_THREAD_CONTEXT_T g_AppThreadContext2;
Имеется панель управления, позволяющая пользователю отправлять события этим двум экземплярам конечного автомата.
int main(int argc, char* argv[])
{
XTHREADHANDLE ThreadHandle = 0;
int ret;
printf("Пример кроссплатформенного таймера состояния: \n");
// Установка функций данных локальной памяти потока.
XTlsAlloc();
SmeSetTlsProc(XSetThreadContext, XGetThreadContext);
////////////////////////////////////////////////////////////////
// Инициализация ядра.
SmeInitEngine(&g_AppThreadContext1); // Инициализация потока-1
XInitMsgBuf();
// Установка функций обработчиков событий.
SmeSetExtEventOprProc(XGetExtEvent, XDelExtEvent,
XPostThreadExtIntEvent, XPostThreadExtPtrEvent, XInitMsgBuf, XFreeMsgBuf);
// Создание потока для запуска внешних событий.
ret = XCreateThread(ConsoleProc, NULL, &ThreadHandle);
// Создание потока приложения Player2
ret = XCreateThread(AppThread2Proc, NULL, &ThreadHandle);
SmeActivateObj(&Player1,NULL);
SmeRun();
printf("Выход из SmeRun() в потоке -1 \n");
XFreeMsgBuf();
XFreeThreadContext(&g_AppThreadContext1); /* Наконец, освобождаются ресурсы локальной памяти потока. */
}
Функция потока второго приложения. Экземпляр конечного автомата Player2 выполняется в данном потоке.
#ifdef WIN32
unsigned __stdcall AppThread2Proc(void *Param)
#else
void* AppThread2Proc(void *Param)
#endif
{
SmeInitEngine(&g_AppThreadContext2); // Инициализация в потоке-2
// Сохранение указателя на контекст потока в локальной памяти потока.
// XSetThreadContext(&g_AppThreadContext2);
XInitMsgBuf();
// Установка функций обработки событий.
SmeSetExtEventOprProc(XGetExtEvent, XDelExtEvent,
XPostThreadExtIntEvent, XPostThreadExtPtrEvent, XInitMsgBuf, XFreeMsgBuf);
SmeActivateObj(&Player2,NULL);
SmeRun();
printf("Выход из SmeRun() в потоке-2 \n");
XFreeMsgBuf();
XFreeThreadContext(&g_AppThreadContext2); /* Наконец, освобождаются ресурсы локальной памяти потока. */
return 0;
}
Панель управления для запуска внешних событий.
#ifdef WIN32
unsigned __stdcall ConsoleProc(void *Param)
#else
void* ConsoleProc(void *Param)
#endif
{
// На платформе Linux вызовите функцию XInitTimer в потоке триггера события простоя.
// При простое поток триггера внешнего события отправляет
// SME_EVENT_TIMER потоку приложения конечного автомата
// и затем вызывает функцию обратного вызова,
// установленную функцией XSetTimer.
XInitTimer();
printf("Вход в поток консольной процедуры.\n");
ConsoleProcUsage();
while(TRUE)
{
int nParam1 =0;
if(g_bQuit) break;
//OSRelated::Sleep(ISVW_LOOP_INTERVAL);
nParam1 = fgetc(stdin);
switch(nParam1)
{
case EOF: return 0;//Отмена ConsoleProc в демоне
case 'x':
case 'X'://Выход
XPostThreadExtIntEvent(&g_AppThreadContext1,
SME_EVENT_EXIT_LOOP, 0, 0, NULL,0,
SME_EVENT_CAT_OTHER);
printf("Прекращение работы потока-1 ... Пожалуйста, подождите. \n");
XPostThreadExtIntEvent(&g_AppThreadContext2,
SME_EVENT_EXIT_LOOP, 0, 0, NULL,0,
SME_EVENT_CAT_OTHER);
printf("Прекращение работы потока -2 ... Пожалуйста, подождите. \n");
return 0;
break;
. . .
default:
break;
}
}
return 0;
}
Дополнительная информация
Вы можете получить дополнительную информацию и загрузить инфраструктуру на основе UML StateChart с открытым исходным кодом и инструментарий IDE (интегрированная среда разработки) здесь.