Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Создание дополнительного потока в консольном приложении




 

См. проект (папку) ThreadsInConsoleMFC. Из приведенного ниже листинга файла ThreadsInConsoleMFC.cpp удалены несущественные части кода: директивы препроцессора, часть сгенерированного мастером MVS кода.

 

/* Иллюстрация создания и использования второго потока в консольном приложении.*/

//…

CWinApp theApp;

using namespace std;

bool Stop=FALSE;

char res[1024];   

char * Rus(char *src)

{

CharToOem(src,res); return res;

}

UINT ComputeInThread(LPVOID pParam)

{

printf(Rus("Второй поток запущен...\n"));

float Sum=0;

for(int i=0;i<30000000;i++)

{

   Beep(rand()/20,50);

   if(Stop) break;

}

printf(Rus("\nВторой поток завершен\n"));

return 0;

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

// …

CWinThread* MyThread;

MyThread=AfxBeginThread(ComputeInThread,0,THREAD_PRIORITY_NORMAL);

// Просто иллюстрация загрузки строки из ресурса.

// В ресурсном файле (.rc) пришлось установить, вручную,

// кодовую страницу 1251 вместо 1252

char szError[MAX_LOADSTRING];

LoadString(0, IDS_Error, szError, MAX_LOADSTRING);

if (!MyThread) printf(Rus(szError));

//     

Sleep(5000); /* задерживаем основной поток для того, чтобы второй
 поток вывел свое сообщение */

//////////////////// поток можно приостанавливать и возобновлять printf(Rus("Приостанавливаем выполнение вт. потока на 2 сек. ...\n"));

MyThread->SuspendThread();

Sleep(2000);

MyThread->ResumeThread();

//

char ch;

do

{

   printf(Rus("Завершить второй поток [y/n]?"));

   ch=getche();

}while(ch!='y');

Stop=TRUE;

getch();

// …

}

 

Несколько комментариев к программе.

Как видно из листинга, даже в консольном приложении можно создавать дополнительные (помимо главного потока – primary thread) потоки. Проще всего это сделать с использованием библиотеки MFC, для чего опять-таки проще всего создать заготовку консольного приложения, которое поддерживает MFC. Для создания дополнительного потока необходимо сделать следующее.

Во-первых, надо написать функцию, которая будет исполняться в этом потоке. Эта функция должна иметь такой прототип:

UINT MyThreadProc(LPVOID pParam);

 

Естественно, что имя функции произвольно (в приведенном выше примере эта функция имеет имя ComputeInThread). Посредством параметра pParam в функцию можно передать любые данные, например, указатель на некоторый объект, как это иллюстрируется в справочной системе MSDN:

 

UINT MyThreadProc( LPVOID pParam )

{

CMyObject* pObject = (CMyObject*)pParam;

if (pObject == NULL ||

   !pObject->IsKindOf(RUNTIME_CLASS(CMyObject)))

return 1; // если pObject недействителен

 

// обрабатываем 'pObject'

 

return 0; // поток завершен успешно

}

 

// в теле какой-либо другой функции программы

pNewObject = new CMyObject;

AfxBeginThread(MyThreadProc, pNewObject); // запуск дополнительного потока

 

Потоку можно как передать любые данные посредством параметра pParam, так и получить результат его работы. К примеру, pParam может быть указателем на структуру.

Во-вторых, надо описать указатель на поток:

CWinThread* MyThread;

 

В-третьих, надо запустить поток на выполнение с помощью функции AfxBeginThread. Эта функция создает поток – объект класса CWinThread, и, в зависимости от значения параметра dwCreateFlags, поток либо будет сразу запущен на выполнение, либо его надо будет запустить с помощью функции CWinThread::ResumeThread().

Поток будет выполняться до тех пор, пока выполняется функция MyThreadProc(). Выполнение потока можно приостанавливать и возобновлять с помощью функций CWinThread::SuspendThread() и  CWinThread::ResumeThread() соответственно.

Проверить фактическое число потоков в своем приложении можно с помощью Диспетчера задач Windows: перейти к вкладке Процессы и добавить с помощью команды Вид|Выбор столбцов столбец Счетчик потоков.

Использование в программе дополнительных потоков вовсе не ограничивается технологией, использованной в приведенной выше программе. Более подробные сведения по программированию многопоточных приложений можно найти в работе [1] и в MSDN.

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




Интеллектуальные указатели

См. Элджер










Последнее изменение этой страницы: 2018-04-12; просмотров: 439.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...