ALTE DOCUMENTE
|
||||||
В принципе, программа может иметь стол&# 19219j918t 1100;ко потоков, сколько их может поддерживать текущая конфигурация операционной системы. Например, новая версия предыдущего примера, которая приводится ниже, создает по команде Новый поток сразу два потока. Для того чтобы убедиться, что параллельно выполняются два потока, они генерирует звуки разной тональности с различными паузами:
include <Windows h>
#include <String.h>
#include <Stdio.h>
#include "Proc.h"
#define Procmax 5
LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);
DWORD MyThread1(LPVOID); //
DWORD MyThread2(LPVOID); //
char szWinName[] = " "; //
char str[255]; // Буфер строки вывода
int X=0, Y=0; // Текущие координаты строки
int procnum=0; // Количество активных процессов
DWORD Tid // Идентификатор 1-го потока
DWORD Tid // Идентификатор 3-го потока
int maxX, maxY; // Размеры экрана
HDC memdc; // DC виртуального окна
HBITMAP hbit; // Растр - это виртуальное окно
HBRUSH hbrush; //
PROCESS_INFORMATION pinfo[Procmax];
int WINAPI WinMain (HINSTANCE hThisInst,
HINSTANCE hPrevInst,
LPSTR lpszArgs,
int nWinMode)
return msg. wParam;
}
// Windows и получает в качестве параметров сообщения
LRESULT CALLBACK WindowFunc HWND hwnd
UINT message,
WPARAM wParam,
LPARAM lParam)
// Не более чем Procmax
// Получить метрики текста */
GetTextMetrics(memdc, &tm);
sprintf(str, "Порождается процесс %d",
procnum);
TextOut(memdc, X, Y, str, strlen(str));
Y = Y+tm.tmHeight+tm.tmExternalLeading;
InvalidateRect hwnd NULL
// Порождение нового процесса
startin.cb=sizeof(STARTUPINFO);
startin.lpReserved = NULL;
startin.lpDesktop = NULL;
startin.lpTitle = NULL;
startin.dwFlags =STARTF_USESHOWWINDOW;
startin.cbReserved2 = 0;
startin.lpReserved2 = NULL;
startin.wShowWindow = SW_SHOWMINIMIZED;
CreateProcess(NULL, "Test.exe", NULL,
NULL, FALSE, 0, NULL,
NULL, &startin,
&(pinfo[procnum]));
procnum++;
break;
case ID_KILLPROC:
if(procnum)
procnum--;
else
// Получить метрики текста
GetTextMetrics memdc, &tm
TerminateProcess
(pinfo[procnum].hProcess, 0);
sprintf(str, " %d ",
procnum);
TextOut(memdc, X, Y, str, strlen(str));
Y = Y+tm.tmHeight+tm.tmExternalLeading;
InvalidateRect(hwnd,NULL,1); //
break;
case ID_THREAD:
CreateThread
(NULL
(LPTHREAD_START_ROUTINE)MyThread1,
(LPVOID)NULL, 0, &Tid1);
CreateThread
(NULL
(LPTHREAD_START_ROUTINE)MyThread2,
(LPVOID)NULL, 0, &Tid2);
InvalidateRect(hwnd, NULL, 1);
break;
case ID_HELP:
MessageBox(hwnd,
"F n"
"F3: Завершить процесс\n"
"F4: Новый поток",
"Помощь:", MB OK
InvalidateRect(hwnd,NULL,1); //
break;
}
break;
case WM_PAINT: //
hdc=BeginPaint(hwnd,&paintstruct); // DC
// Теперь копируем растр из памяти на экран
BitBlt(hdc,0,0,maxX,maxY,memdc,0,0,SRCCOPY);
EndPaint(hwnd,&paintstruct); // DC
break;
case WM_DESTROY: // Завершение программы
DeleteDC(memdc); // Удалить виртуальное окно
PostQuitMessage(0);
break;
default:
// Все сообщения, не обрабатываемые в данной
// функции, направляются на обработку по
// умолчанию
return DefWindowProc(hwnd,message,
wParam,lParam);
return 0;
}
DWORD MyThread1(LPVOID param)
return
}
DWORD MyThread2(LPVOID param)
return
}
CreateThread
При работе со многими процессами или потоками нередко требуется синхронизировать функционирование двух или более из них. Причиной этого чаще всего является необходимость обеспечить доступ нескольких потоков к одному и тому же ресурсу, который может использоваться одновременно тол&# 19219j918t 1100;ко одним потоком. Например, если один поток записывает информацию в файл, все другие потоки не могут в данный момент времени этот файл использовать. Механизм предотвращения таких ситуаций называется сериализацией. Другой причиной может быть ожидание одним потоком некоего события, которое может наступить лишь при выполнении другого потока. Для таких случаев должны быть предусмотрены специальные средства, с помощью которых первый поток будет переведен в состояние ожидания до возникновения соответствующего события, а после этого продолжит выполнение.
Windows R (например, к файлу или базе данных на диске), который в каждый момент времени может использоваться тол&# 19219j918t 1100;ко одним процессом.
R flag R flag R
while flag
; // Ожидание сброса флага
flag
//
// ... Работа с ресурсом R
//
flag // Сброс флага
flag
R while flag flag flag flag R while flag flag while flag R flag не рассматривается в многозадачной операционной системе как непрерывная операция. И поэтому не имеет значения, какие средства Вы будете использовать: так или иначе на уровне приложения не существует способа блокировки ресурса, который бы давал полную гарантию того, что этот ресурс в каждый момент времени будет доступен тол&# 19219j918t 1100;ко одному процессу.
Windows test and set operation semaphores Windows
Windows Windows поддерживаются четыре типа объектов синхронизации. Все они, так или иначе, базируются на концепции семафора. Первый тип представляет собой классический семафор и может быть использован для управления доступом к определенным ресурсам ограниченного количества процессов или потоков. Причем ресурс может быть либо полностью сериализован и в этом случае использоваться в каждый момент времени одним и тол&# 19219j918t 1100;ко одним процессом, либо же небольшому числу процессов или потоков может быть разрешен одновременный доступ к ресурсу. Семафоры реализуются как простые счетчики, значения которых увеличиваются, когда процесс освобождает семафор, и уменьшаются при использовании семафора процессом или потоком.
mutex) семафором. Исключающие семафоры применяются для сериализации ресурсов таким образом, что в каждый момент времени их может использовать один и тол&# 19219j918t 1100;ко один процесс или поток. Исключающий семафор представляет собой нечто иное, как специальный тип обычного семафора.
event object
critical section и могут быть определены при помощи объектов критических секций. При вхождении потока в критическую секцию никакой другой поток не может начать выполнение этой секции до того, как работающий с ней поток не выйдет из нее. Критические секции применяются тол&# 19219j918t 1100;ко по отношению к потокам.
Windows
CreateSemaphore
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpAttr,
LONG InitialCount,
LONG MaxCount,
LPSTR lpszName);
lpAttr NULL Windows
доступ к объекту, задается значением параметра MaxCount mutex
InitialCount InitialCount MaxCount
lpszName NULL
CreateSeniaphore NULL
WaitForSingleObject ReleaseSemaphore
DWORD WaitForSingleObject(HANDLE hObject,
DWORD dwHowLong);
BOOL ReleaseSemaphore (HANDLE hSema,
LONG Count,
LPLONG lpPrevCount
WaitForSingleObject hObject dwHowLong INFINITE WAIT OBJECT WAIT TIMEOUT WaitForSingleObject
ReleaseSemaphore hSema Count lpPrevCount LONG NULL
|