| Форум| Гостевая| Ссылки| Программы| Исходные тексты| Наши партнеры.|
   
| Главная| Рассылки| Услуги| Библиотека| Новости| Авторам| Программистам| Студентам|
delphi c++ assembler
 

Шаг 116 - EnterCriticalSection, LeaveCriticalSection и InitializeCriticalSection.

Очень полезно сначала прочитать "Шаг 80 - Что такое критическая секция (Critical Section)", так как именно эти функции относятся к критической секции. Давайте посмотрим пример. Следующий код выполянет ряд действий над массивом.

// TestCritical.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"

#define MAX_ARRAY 5


int array[MAX_ARRAY];

void EmptyArray();
void PrintArray();
void FullArray();

void main()
{
	EmptyArray();
	PrintArray();
	FullArray();
	PrintArray();
	EmptyArray();
	PrintArray();
}

void EmptyArray()
{
	for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=0;
	Sleep(1000);
}

void PrintArray()
{
	for (int x=0;x<(MAX_ARRAY+1); x++) cout << array[x] << " ";
	cout << endl;
	Sleep(1000);
}

void FullArray()
{
	for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=x;
	Sleep(1000);
}

В данном примере все нормально. У нас всего один поток. Этот поток последовательно выполнит все действия над распределенным объектом array. Почему он распределенный ? Потому, что он определен глобально и к нему можно обратиться в любой момент. Так вот, если у нас будет несколько потоков все станет сложнее. Одна фунция не успеет очистить массив, а вторая может уже начать писать или печатать не до конца очищенный массив. Вот для решения этих проблем и используются критические секции. В тот код, который правит распределенный ресурс и является критической секцией. Для объявления начала критической секции используется функция.

VOID EnterCriticalSection
(
  LPCRITICAL_SECTION lpCriticalSection  // указатель на переменную критическая секция.
);
А для выхода из критической секции. VOID LeaveCriticalSection ( LPCRITICAL_SECTION lpCriticalSection // указатель на переменную критическая секция. ); Для работы с критической секцией нам нужна переменная типа - критическай секция. Вот она.
CRITICAL_SECTION
Перед тем как использовать критическую секцию ее надо проинициализировать.
VOID InitializeCriticalSection
(
  LPCRITICAL_SECTION lpCriticalSection  // указатель на переменную критическая секция.
);

// TestCritical.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h" 

#define MAX_ARRAY 5

CRITICAL_SECTION critsect;

int array[MAX_ARRAY];

void EmptyArray(void *);
void PrintArray(void *);
void FullArray(void *);

void main()
{

	InitializeCriticalSection(&critsect);
	if (_beginthread(EmptyArray,1024,NULL)==-1) cout << "Error begin thread " << endl; 
	if (_beginthread(PrintArray,1024,NULL)==-1) cout << "Error begin thread " << endl; 
	if (_beginthread(FullArray,1024,NULL)==-1)  cout << "Error begin thread " << endl;
	if (_beginthread(PrintArray,1024,NULL)==-1) cout << "Error begin thread " << endl;
	if (_beginthread(EmptyArray,1024,NULL)==-1) cout << "Error begin thread " << endl;
	if (_beginthread(PrintArray,1024,NULL)==-1) cout << "Error begin thread " << endl; 
	Sleep(10000);
}

void EmptyArray(void *)
{
	cout << "EmptyArray" << endl;
	EnterCriticalSection(&critsect);
	for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=0;
	Sleep(1000);
	LeaveCriticalSection(&critsect);
	_endthread();
}

void PrintArray(void *)
{
	cout << "PrintArray" << endl;
	EnterCriticalSection(&critsect);
	for (int x=0;x<(MAX_ARRAY+1); x++) cout << array[x] << " ";
	cout << endl;
	Sleep(1000);
	LeaveCriticalSection(&critsect);
	_endthread();
}

void FullArray(void *)
{
	cout << "FullArray" <<
 endl;
	EnterCriticalSection(&critsect);
	for (int x=0;x<(MAX_ARRAY+1); x++) array[x]=x;
	Sleep(1000);
	LeaveCriticalSection(&critsect);
	_endthread();
}
Результат работы будет вот такой.
EmptyArray
PrintArray
FullArray
PrintArray
EmptyArray
PrintArray
0 0 0 0 0 0
0 1 2 3 4 5
0 0 0 0 0 0

Потоки запускаются, начинается доступ к критичекой секции. Дожидаются своей очереди и выполняют необходимые действия. Не забудьте установиь опции многопоточного проекта, как в шаге ActiveX: "Шаг 78 - Что понимается под условиям гонки (rase condition)".


Предыдущий Шаг | Следующий Шаг | Оглавление

By Artem.
Используются технологии uCoz
 

Rambler's Top100 Rambler's Top100

©  Adept Design Studio

Используются технологии uCoz