Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСиСП. Часть 2. Контрольная работа 2.doc
Скачиваний:
90
Добавлен:
01.04.2014
Размер:
190.98 Кб
Скачать

Три варианта завершения текущего процесса

#defineEXIT_CODE 0xFF

void main (void)

{

     ExitProcess(EXIT_CODE);

}

void main(void)

{

     TerminateProcess(GetCurrentProcess(), EXIT_CODE);

}

void main(void)

{

    return EXIT_CODE;

}

  1. Поток

Поток (Thread) – объект ядра, отвечающий за выполнение программного кода в процессе. При инициализации процесса система создаёт и его первичный поток. Первичный поток начинает своё выполнение с функции main (в консольных приложениях) или с WinMain (GUI-приложения) и существует до тех пор, когда main (WinMain) возвращает управление. Большинство процессов обходятся одним потоком, однако существует возможность создания новых потоков, которые будут выполнять программный код параллельно с первичным потоком. На многопроцессорных системах эти потоки будут работать действительно параллельно (под управлением Windows NT/2000); на системах с одним процессором, ОС будет последовательно переключать процессор между всеми запущенными потоками.

На уровне ОС поток представляется блоком потока с информационными структурами:

  • идентификатор потока TID (Thread ID)

  • стартовый адрес потока

  • данные о стеках потока:

    • пользовательского режима;

    • режима ядра;

  • информация о контексте потока

  • информация для диспетчеризации

  • время создания/завершения

  • информация о локальной памяти потока (TLS)

    1. Создание потоков

Для создания нового потока в процессе применяется функция CreateThread. Каждый поток начинает своё выполнение с заданной функции и заканчивает при возврате из подпрограммы или при вызове функции ExitThread либо TerminateThread.

Пример 2. Программа создаёт два потока, печатающих на экране символы "*" и "!"

#include <iostream>

#include <windows.h>

// Функция, исполняемоя потоками.

// Выводит заданный параметром p символ

DWORD __stdcall CharsThread(LPVOID p)

      // LPVOID p есть указатель на символ

     TCHAR c = *(TCHAR*)(p);

     // Бесконечно выводим на экран символ

     while(1)

     {

         std::cout << c;

     }

     return 0;

 }

int _tmain(int argc, _TCHAR* argv[])

{

    // Описатели потоков

    HANDLE hThreads[2]; 

    TCHAR asterisk = '*';

    TCHAR exclam = '!';

    // Поток, печатающий '*'

    hThreads[0] = CreateThread(NULL, 0, CharsThread, &asterisk, 0, NULL);

    // Поток, печатающий '!' 

    hThreads[1] = CreateThread(NULL, 0, CharsThread, &exclam, 0, NULL);

    // Время ожидания завершения потоков

    #define TIMEOUT 2000

    // Ждём завершения двух потоков TIMEOUT миллисекунд

    WaitForMultipleObjects(2, hThreads, TRUE, TIMEOUT); 

    /* Закрываем описатели потоков. Сами потоки продолжают работать до завершения процесса */

    CloseHandle(hThreads[0]);

    CloseHandle(hThreads[1]);

    return 0;

}

    1. Завершение работы потока

Поток может завершиться:

  • при возврате из функции потока;

  • при вызове потоком функции ExitThread;

  • при вызове самим потоком либо другим потоком функции TerminateThread;

  • при завершении процесса, которому принадлежит поток.

Пример 3. Программа останавливает работу потока, выполняющего бесконечный цикл, если он не завершится за 5000 мс (5 секунд)

// Функция потока с бесконечным циклом

DWORD __stdcall Loop(LPVOID lpParam)

{

   for(;;);

   return 0;

}

int main(int argc, char* argv[])

{

   HANDLE hThread; // Описатель потока

   // Запуск потока с бесконечным циклом

   hThread = CreateThread(NULL, 0, Loop, NULL, 0, NULL);

   // Ждём окончания работы потока 5000 мс.

   if ( WAIT_OBJECT_0 != WaitForSingleObject(hThreads, 5000))

   {

      // Прерывание потока с кодом возврата 0xFF

      TerminateThread(hThread, 0xFF);

   }

   // Закрываем описатель потока. (Не забываем!!!)

   CloseHandle(hThread);

   return 0;

}