Опубликован: 24.04.2009 | Уровень: специалист | Доступ: платный
Лекция 8:

Программирование приложений в CE

Пример программы с потоком и событием синхронизации

Программа C/C++ Thread_Demo показывает, как создать поток, используя вызов API CreateThread. Основной процесс и поток оба печатают строку консольного сообщения, каждый раз при выполнении итерации цикла. Потоки обычно необходимо синхронизировать с другими событиями, в данном случае мы будем предполагать, что он должен синхронизироваться с каждой итерацией цикла основного процесса, который создал поток. На рисунке 8.2 никакая синхронизация не используется, и поток выполняется несколько раз, прежде чем основная программа заканчивает одну итерацию цикла. Функция Sleep используется для моделирования, что каждый поток имеет существенно отличное время выполнения, так чтобы любые проблемы синхронизации были более очевидны.

Поток, выполняющийся без синхронизации, может выполниться несколько раз до основной программы

увеличить изображение
Рис. 8.2. Поток, выполняющийся без синхронизации, может выполниться несколько раз до основной программы

На рисунке 8.3 было добавлено событие синхронизации, чтобы сохранить основной поток и рабочий поток синхронизированными на одной и той же итерации. Код синхронизации можно видеть в строках комментариев в цикле while в конце кода.

Поток, использующий WaitForSingleObject для ожидания события синхронизации

увеличить изображение
Рис. 8.3. Поток, использующий WaitForSingleObject для ожидания события синхронизации

Функция CreateEvent задает событие, SetEvent сигнализирует о событии, а WaitForSingleObject блокирует рабочий поток, пока событие не будет задано основным потоком. Другие доступные в API CE методы синхронизации включают мьютексы, семафоры и критические разделы.

Будут ли потоки по прежнему синхронизированы, если рабочий поток имеет очень длинное время выполнения, или что-то другое в системе заставляет его выполнять итерацию медленнее? Измените код (подсказка: Sleep) и проверьте. Если они не полностью синхронизированы, как можно было бы исправить проблему?

// Thread_Demo.cpp : Определяет точку входа для консольного приложения.
//
// Пример, который показывает, как создать и синхронизировать поток 
// с помощью события 
//
#include "stdafx.h"
//Функция потока (Thread)
DWORD WINAPI WorkerThread (LPVOID lpArg);
HANDLE g_hMainEvent = 0;


int _tmain(int argc, TCHAR *argv[], TCHAR *envp[])
{
	HANDLE hThread1;
	DWORD dwThread1ID = 0;
	INT nParameter = 1;
	int count1 = 0;
	printf(" \n");
       _tprintf(_T("   Hello Thread World!\n"));
	g_hMainEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
	Sleep(1000);
	hThread1 = CreateThread (NULL, 0, WorkerThread, (LPVOID)nParameter, 0, &dwThread1ID);
	while (count1 < 100){
		printf("   main thread computes value: %d\n",count1);
		count1++;
		SetEvent(g_hMainEvent);
		Sleep(370);
	}
	CloseHandle(hThread1);
	CloseHandle(g_hMainEvent);
    return 0;
}
DWORD WINAPI WorkerThread (LPVOID lpArg) {
	INT threadnumber = (INT) lpArg;
	INT count = 0;
	INT RunCode;
	while (1){
//		RunCode = WaitForSingleObject(g_hMainEvent, INFINITE);
//		if (RunCode == WAIT_OBJECT_0){
printf("   worker thread %d computes value %d\n", threadnumber, count);
		count++;
		Sleep(50);
//		}
	}
	return 0;
 }

Удаленные инструменты ( Tools \Rightarrow Remote Tools ) будут полезны для вывода информации о процессах и потоках, выполняющихся на целевой системе. Просмотрщик Remote Process выводит информацию о каждом выполняющемся процессе и потоке. Если выделить процесс, то кнопка с красным символом "X" будет убивать процесс. Удаленная утилита Kernel Tracker графически выводит процессы и события синхронизации относительно времени. Она выполняется быстрее, когда уменьшается числа объектов представления информации.

Просмотрщик процессов можно использовать для проверки статуса процессов и потоков

увеличить изображение
Рис. 8.4. Просмотрщик процессов можно использовать для проверки статуса процессов и потоков
Утилита Kernel tracker показывает, какой процесс выполняется, и выводит события синхронизации

увеличить изображение
Рис. 8.5. Утилита Kernel tracker показывает, какой процесс выполняется, и выводит события синхронизации
Утилита Kernel tracker выводит все эти события

Рис. 8.6. Утилита Kernel tracker выводит все эти события

Другие удаленные инструменты, которые можно попробовать использовать, и которые могут оказаться полезны, включают:

  • Zoom – используется для удаленного захвата экрана
  • Remote Registry Editor – Редактирование и просмотр реестра целевого устройства
  • Remote File Viewer – просмотр файлов на целевом устройстве, загрузка (экспорт) файла
  • Heap Walker - выводит информацию о куче.
  • Call Profiler - предоставляет графический интерфейс для профилирования и анализа.
  • Spy – выводит список окон, открытых на целевом устройстве, и сообщения.
Бахтиёр Бутаев
Бахтиёр Бутаев
Таджикистан, Душанбе, Таджикский Технический Университет (ТТУ), 2013
Ярославй Грива
Ярославй Грива
Россия, г. Санкт-Петербург