К Т П           План занятия                                                        1                                           Страницы  | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | | 7 | | 8 | | 9 |

3. Условная замена значения переменной

Для условной замены значения переменной в операционных системах Windows используется блокирующая функция InterlосkedСоmpareExchange, которая имеет следующий прототип:
PVOID InterlockedCompareExchange (
  PVOID *Destination,  // адрес переменной, значение которой заменяется
  PVOID Exchange,     // новое значение переменной
  PVOID Comperand   // значение для сравнения
) ;

Эта функция предназначена для замены значения переменной, адрес которой задан параметром Destination, на новое значение, которое задано параметром Exchange, при условии, что старое значение переменной равно значению, заданному параметром comperand. Значение, возвращаемое функцией InterlockedCompareExchange, равно старому значению изменяемой переменной.

Замечание: Адреса всех переменных, используемых функцией InterlockedCompareExchange, должны быть выровнены на границу слова, т. е. должны быть кратны 32.

В листинге 7.2 приведен пример использования функции InterlockedCompareExchange для условной замены значения переменной. Эта программа отличается от программы из листинга 7.1 только тем, что поток producer будет помещать новое число в контейнер только в том случае, если поток consumer освободил контейнер от старого числа.

Листинг 7.2. Пример использования функции InterlockedCompareExchange

#include <windows.h>
#include <iostream.h>

volatile long n;

void producer()
{
long goods = 0;
for (;;)
{
++goods; // производим новое число
// помещаем число в контейнер, если он пустой
InterlockedCompareExchange((PVOID*)&n, (PVOID)goods, 0);
Sleep(150);
}
}

void consumer()
{
long goods;
for (;;)
{
Sleep(400);
goods = n; // извлекаем число из контейнера
InterlockedExchange((LONG*)&n, 0); // отмечаем, что контейнер пустой
cout << "Goods are consumed: " << goods << endl;
}
}

int main()
{
HANDLE hThread_p, hThread_c;
DWORD IDThread_p, IDThread_c;

cout << "Press any key to terminate threads." << endl;
// создаем потоки
hThread_p = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)producer,
NULL, 0, &IDThread_p);
if (hThread_p == NULL)
return GetLastError();
hThread_c = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)consumer,
NULL, 0, &IDThread_c);
if (hThread_c == NULL)
return GetLastError();

cin.get();

// прерываем выполнение потоков
TerminateThread(hThread_p, 0);
TerminateThread(hThread_c, 0);

// закрываем дескрипторы потоков
CloseHandle(hThread_c);
CloseHandle(hThread_p);

return 0;
}

 


Предыдущая        В начало страницы       Следующая
3