Библиотека генетических алгоритмов - часть 2 - Организация поточной обработки

ОГЛАВЛЕНИЕ

Организация поточной обработки

Библиотека генетических алгоритмов содержит набор классов, типов данных и макросов, изолирующих зависящую от платформы организацию поточной обработки. Класс GaThread обертывает и управляет системными потоками.

 

Схема – Класс GaThread

Перечисление GaThreadStatus определяет возможные состояния потока, и структура GaThreadParameter хранит начальные параметры потока.

Типы данных потоков определены библиотекой:

SystemThread

Этот тип определяет системно-специфический тип для хранения объектов потока.

ThreadID

Переменные/объекты этого типа хранят идентификаторы системных потоков. Этот тип прячет системно-специфические типы, используемые для данных целей.

ThreadFunctionPointer

Этот тип определяет указатель на функцию, служащую входной точкой потока.

ThreadFunctionReturn

Этот тип является типом возвращаемого значения для функции, служащей входной точкой потока.

GaCriticalSection изолирует системно-специфическую защиту критических секций от одновременного доступа к ним нескольких потоков. Класс GaSectionLock используется для автоматической блокировки и разблокировки объектов критической секции.

// ...

GaCriticalSection _criticalSection;

// ...

void SomeMethod()
{
    // автоматически блокирует объект синхронизации _criticalSection
    GaSectionLock lock( &_criticalSection, true );

    // ...код критической секции...

    // объект блокировки уничтожается, когда выполнение покидает эту область
    // деструктор объекта снимает блокировку с используемого объекта критической секции
}

 

Схема – Классы GaCriticalSection и GaSectionLock

Библиотека генетических алгоритмов определяет макросы, облегчающие синхронизацию с объектами критической секции. Эти макросы описаны далее.

Типы данных синхронизации:

SysSyncObject

Этот тип определяет системно-специфические объекты синхронизации, используемые классом GaCriticalSection.

SysSemaphoreObject

Этот тип определяет системно-специфические объекты семафора.

SysEventObject

Этот тип определяет системно-специфические объекты события.

Функции синхронизации:

bool MakeSemaphore(
    SysSemaphoreObject& semaphore,
    int maxCount,
    int initialCount);

Эта функция применяется для создания объекта операционной системы для семафора и его инициализации.

bool DeleteSemaphore(
    SysSemaphoreObject& semaphore);
 

Эта функция применяется для освобождения объекта семафора операционной системы.

bool LockSemaphore(
    SysSemaphoreObject& semaphore);

Эта функция применяется для получения доступа к критической секции, защищенной семафором.

bool UnlockSemaphore(
    SysSemaphoreObject& semaphore,
    int count);

Эта функция применяется для освобождения доступа к критической секции, защищенной семафором.

bool MakeEvent(
    SysEventObject& event,
    bool intialState);

Эта функция применяется для создания объекта операционной системы для события и его инициализации.

bool DeleteEvent(
    SysEventObject& event);

Эта функция применяется для освобождения объекта события операционной системы.

bool WaitForEvent(
    SysEventObject& event);

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

bool SignalEvent(
    SysEventObject& event);

Эта функция применяется для установки события в сигнальное состояние.

Макросы синхронизации:

 

ATOMIC_INC(VALUE)

Атомарно увеличиваетVALUE на единицу и возвращает новое значение.

 

ATOMIC_DEC(VALUE)

Атомарно уменьшаетVALUE на единицу и возвращает новое значение.

 

SPINLOCK(LOCK)

Защищает критическую секцию с помощью взаимоблокировки.LOCK должен быть переменной типаint. ДляснятиявзаимоблокировкипеременнаяLOCK должна быть установлена в0.

 

DEFINE_SYNC_CLASS

Этот макрос вставляет члены в класс, необходимые для синхронизации доступа к экземпляру класса. МакросыLOCK_OBJECT иLOCK_THIS_OBJECT применяются для синхронизации доступа к объекту.

 

LOCK(LOCK_NAME)

Этот макрос применяется для получения доступа к критической секции, защищенной объектом синхронизации (GaSectionLock или GaCriticalSection).

 

UNLOCK(LOCK_NAME)

Этот макрос используется, когда поток уходит из критической секции и освобождает доступ к объекту синхронизации (GaSectionLock orGaCriticalSection).

 

LOCK_OBJECT(LOCK_NAME,OBJECT)

Этот макрос получает доступ к объекту с встроенным синхронизатором и предотвращает одновременный доступ. Он создает экземпляр объекта GaSectionLock с именемLOCK_NAME и получает доступ к объекту. Когда выполнение покидает область, в которой задан LOCK_OBJECT, объектGaSectionLock уничтожается, и освобождается доступ к заблокированному объекту. Разблокировать доступ к объекту перед уходом из области видимости можно путем вызова макросаUNLOCK(LOCK_NAME).

 

LOCK_THIS_OBJECT(LOCK_NAME)

Этот макрос получает доступ к текущему объекту и предотвращает одновременный доступ. Он объявляет и создает экземпляр объектаGaSectionLock с именемLOCK_NAME и получает доступ к текущему объекту. Когда выполнение покидает область, в которой заданLOCK_OBJECT, объектGaSectionLock уничтожается, и освобождается доступ к текущему объекту. Разблокировать доступ к объекту перед уходом из области видимости можно путем вызова макросаUNLOCK(LOCK_NAME).

Чтобы синхронизировать доступ к объекту с помощью макросов LOCK_OBJECT и LOCK_THIS_OBJECT, класс объекта должен использовать макрос DEFINE_SYNC_CLASS, вставляющий члены, используемые этими макросами.

Вставляются следующие члены:

•    атрибут mutable(изменяемый) GaCriticalSection _synchronizator и
•    метод GaCriticalSection* GACALL GetSynchronizator() const

class SomeClass
{
    DEFINE_SYNC_CLASS

    // остальная часть объявления класса
};

Пользователь может использовать макросы для синхронизации доступа к объекту класса.

void SomeMethod()
{
    SomeClass obj;

    // Объявляет объект GaSectionLock obj_lock,
    // использующий объект критической секции, встроенный в объект obj
    LOCK_OBJECT( obj_lock, obj );

    // ...код критической секции...

    // блокировка снимается автоматически
    // путем уничтожения объекта obj_lock
}
void SomeClass::SomeMethod()
{
    // Объявляет объект GaSectionLock obj_lock,
    // использующий объект критической секции, встроенный в текущий объект
    LOCK_THIS_OBJECT( obj_lock );

    // ...код критической секции...

    // блокировка снимается автоматически
    // путем уничтожения объекта obj_lock
}

Если критическая секция завершается раньше конца области видимости, макрос UNLOCK может использоваться для разблокировки объекта критической секции.

void SomeClass::SomeMethod()
{
    // Объявляет объект GaSectionLock obj_lock,
    // использующий объект критической секции, встроенный в текущий объект
    LOCK_THIS_OBJECT( obj_lock );

    // ...код критической секции...

    // снимается блокировка с объекта критической секции
    UNLOCK( obj_lock );

    // ...некритический код...

    // секцию можно снова заблокировать с использованием того же объекта блокировки
    LOCK( obj_lock );

    // ...критическая секция...
}

Можно заблокировать критическую секцию без применения объектов GaSectionLock. Макросы LOCK и UNLOCK можно применять непосредственно к объектам критической секции.

// ...

GaCriticalSection _criticalSection;

// ...

void SomeMethod()
{
    // блокируется объект критической секции
    LOCK( _criticalSection );

    // ...код критической секции...

    // снимается блокировка
    UNLOCK( _criticalSection );
}