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

5. Изменение значения переменной

Для изменения значения переменной в операционных системах Windows используется блокирующая функция InterlockedExchangeAdd, которая имеет следующий прототип:
LONG InterlockedExchangeAdd (
  LPLONG IpAddend, // адрес переменной, значение которой изменяется
  LONG Increment // прибавляемое значение
);

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

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

В листинге 7.4 приведен пример использования функции InterlockedExchangeAdd для взаимоисключающего увеличения значения переменной. Эта программа отличается от программы из листинга 7.3 только тем, что значение переменной п увеличивается не на 1, а на 10.

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

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

volatile long n;

void producer()
{
for (;;)
{
/* изменяем число в контейнере */
InterlockedExchangeAdd((long*)&n, 10);
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;
}

 


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