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

4. Инкремент и декремент переменной

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

Функция Interlockedlncrement имеет следующий прототип:
LONG Interlockedlncrement (
  LPLONG IpAddend // адрес переменной для инкремента
);

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

Функция InterlockedDecrement имеет следующий прототип:
LONG InterlockedDecrement (
  LPLONG IpAddend // адрес переменной для декремента
);

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

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

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

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

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

volatile long n;

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

 


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