Создание потоков (MFC)
Страница 2.




Синхронизация работы нескольких потоков

Для синхронизации нескольких потоков используют следующие объекты: критические секции, семафоры, защелки.

1. Критические секции.

Критические секции используются для контроля доступа к защищенным данным.

Их можно использовать внутри одного класса для синхронизации чтения-доступа к данным.
class cls
{
private:
   
int val;
   
CCriticalSection section;
public:
   
void write(int);
   
void read(int*);
}

void cls::write(int n)
{
   
section.Lock();
   
val=n;
   
section.Unlock();
}

void cls::read(int * n)
{
   
section.Lock();
   *
n=val;
   
section.Unlock();
}
При вызове метода Lock() происходит блокировка секции, и последующие вызовы этого метода не возвратят управление вызывающему потоку до тех пор, пока секция не будет освобождена.
Из данного примера видно, что при записи нового значения невозможно прочитать старое. Соответственно при чтении значения его невозможно изменить. Если в работе участвуют большие объемы данных, то для предотвращения сбоя необходим контроль. Критические секции обеспечивают минимальную защиту от сбоев.

2. Защелки(MUTEXes)

Использование защелок CMutex при синхронизации потоков одного приложения не отличается от использования критических секций. Работа с ними осуществляется с использованием следующих объектов: CSingleLock и CMultiLock. Для получения доступа к защелке используется методо Lock(). Для освобождения защелки нужно вызвать метод Unlock()
CMutex mutex;  //создание защелки

CSingleLock sLock(&mutex);  //захват защелки

sLock.Lock();

sLock.Unlock();  //освобождение защелки

class cls
{
private:
   
int val;
   
CMutex mutex;
public:
   
void write(int);
   
void read(int*);
}

void cls::write(int n)
{
   
CSingleLock sLock(&mutex);

   
sLock.Lock();
   
val=n;
}

void cls::read(int * n)
{
   
CSingleLock sLock(&mutex);

   
sLock.Lock();
   *
n=val;
}
Использование метода Unlock() в данном случае необязательно т.к. при вызове деструктора sLock защелка автоматически освобождается.

3. Семафор

Использование этого объекта ничем не отличается от использования предыдущих. Разница заключается в том, что семафор дает право на использование контролируемых параметров определенному числу потоков. В семафоре хранится количество объектов, которые в данный момент имеют доступ к данным.
CSemaphore semaphore(2,2);  //создание семафора
При создании семафора указывается начальное и максимальное значение счетчика
CSingleLock sLock(&semaphore);  //Захват семафора
sLock.Lock();
При вызове метода Lock() значение счетчика внутри семафора уменьшается. Когда оно достигнет нуля, метод Lock() будет ждать освобождения семафора. После этого захватит семафор и вернет управление вызывающей функции
sLock.Unlock();  //Освобождение семафора
 
« Предыдущая статья   Следующая статья »