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

2. Замена значения переменной

Для замены значения переменной в операционных системах Windows используется блокирующая функция InterlоckedЕхchange, которая имеет следующий прототип:
LONG InterlockedExchange(
LPLONG lpTarget, // адрес переменной, значение которой заменяется
LONG lValue // новое значение переменной
);

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

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

В листинге 7.1 приведен пример использования функции InterlockedExchange для взаимоисключающей замены значения переменной. В этой программе поток producer производит товары — целые числа, а поток consumer потребляет эти товары. После того как товар произведен, он помещается потоком producer в контейнер, роль которого выполняет переменная n. Чтобы потребить товар, поток consumer должен забрать его из контейнера. Требуется, чтобы операции загрузки нового товара в контейнер и извлечение товара из контейнера не прерывали друг друга. Для выполнения этого требования в программе и используется функция InterlockedExchange.

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

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

volatile long n;

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

void consumer()
{
long goods;
for (;;)
{
Sleep(400);
InterlockedExchange(&goods, n); // извлекаем число из контейнера
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;
}

 


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