| Форум| Гостевая| Ссылки| Программы| Исходные тексты| Наши партнеры.|
   
| Главная| Рассылки| Услуги| Библиотека| Новости| Авторам| Программистам| Студентам|
delphi c++ assembler
 

Шаг 117 - CreateSemaphore, ReleaseSemaphore.

Очень полезно сначало прочитать MSDN: "Шаг 81 - Что такое семафоры (Semaphore)". Создается семафор функцией CreateSemaphore():

HANDLE CreateSemaphore
(
  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // атрибут доступа
  LONG lInitialCount,                          // инициализированное начальное состояние счетчика
  LONG lMaximumCount,                          // максимальное количество обращений
  LPCTSTR lpName                               // имя объекта
);

При успешном выполнении функция вернет идентификатор семафора, в противном случае NULL. После того как необходимость в работе с объектом отпала нужно вызвать функцию ReleaseSemaphore(), чтобы освободить счетчик.

BOOL ReleaseSemaphore
(
  HANDLE hSemaphore,       // хенд семафора
  LONG lReleaseCount,      // на сколько изменять счетчик
  LPLONG lpPreviousCount   // предыдущее значение
);

При успешном выполнении возвращаемое значение ненулевое. Для уничтожения семафора нужно вызвать CloseHandle(). Давайте рассмотрим пример. Вот он:

// TestSemaphore.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "process.h" 

HANDLE hSemaphore;
LONG cMax = 2;

void Test1(void *);
void Test2(void *);
void Test3(void *);

void main()
{
hSemaphore = CreateSemaphore( 
    NULL,   // нет атрибута
    cMax,   // начальное состояние
    cMax,   // максимальное состояние
    NULL);  // без имени

if (!hSemaphore == NULL) 
{
	if (_beginthread(Test1,1024,NULL)==-1)
		cout << "Error begin thread " << endl;
	if (_beginthread(Test2,1024,NULL)==-1)
		cout << "Error begin thread " << endl;
	if (_beginthread(Test3,1024,NULL)==-1)
		cout << "Error begin thread " << endl;
	Sleep(10000);
	CloseHandle(hSemaphore);
}
else cout << "error create semaphore" << endl;
}

void Test1(void *)
{
cout << "Test1 Running" << endl;
DWORD dwWaitResult; 
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject( 
        hSemaphore,   // указатель на семафор
        1);          // интерфал ожидания
cout << "Test 1 TIMEOUT" << endl;
}
Sleep(1000);
if (ReleaseSemaphore(       
	    hSemaphore,  // указатель на светофор
        1,           // изменяет счетчик на 1
        NULL))   cout << " ReleaseSemaphore Ok Test1" << endl;   
_endthread();
}

void Test2(void *)
{
cout << "Test2 Running" << endl;
DWORD dwWaitResult;
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject(hSemaphore,1);
cout << "Test 2 TIMEOUT" << endl;
}
Sleep(1000);
if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout << " ReleaseSemaphore Ok Test2" << endl;  
_endthread();
}

void Test3(void *)
{
cout << "Test2 Running" << endl;
DWORD dwWaitResult; 
while(dwWaitResult!=WAIT_OBJECT_0)
{
dwWaitResult = WaitForSingleObject(hSemaphore,1);
cout << "Test 3 TIMEOUT" << endl;
}
if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout << " ReleaseSemaphore Ok Test3" << endl;  
_endthread();
}

В данном примере создается семафор. Запускаются три потока, каждый из которых обрашается к семафору. Вот только разрешается обращаться всего двум потокам. Поэтому Test3 будет ждать, пока кто-то освободит семафор. Вот результат:

.......
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
Test 3 TIMEOUT
 ReleaseSemaphore Ok Test1
Test 3 TIMEOUT
 ReleaseSemaphore Ok Test2
 ReleaseSemaphore Ok Test3
Press any key to continue

Как видите третий поток ждет. И как только освободился семафор он может дальше что-то делать.


Предыдущий Шаг | Следующий Шаг | Оглавление

By Artem.
Используются технологии uCoz
 

Rambler's Top100 Rambler's Top100

©  Adept Design Studio

Используются технологии uCoz