![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Semaphore vs Mutex [D7, NT4, Win2k, WinXP]
Shaman O Mega © (2003-10-29 16:01:00)
Я пишу многопоточный многопользовательский сервер, при подключении клиента я создаю семафор с его именем и ip адрессом (в одном потоке ), затем когда пользователь выходит я пытаюсь уничтожить этот семафор (это уже другой поток, но того же процесса), однако у меня ничего не получается... С мьютексами та же проблема. :) помогите дураку
Digitman (2003-10-30 10:31:00) [1]
> здесь похоже всех больше интересует оптимизация
до оптимизации еще и речи не дошло) ... ты так и не сказал, какой ресурс в каком контексте-масштабе ты пытаешься защитить) ... это, видимо, великий и непостижимы секрет)
ну вот смотри, попытаюсь проиграть твою ситуацию в псевдокоде, как я ее вижу :
var
SessionLock: TCriticalSection;
SessionList : TStringList;
...
// поиск индекса активной.сессии в списке актив.сессий
function GetExistingSession(ClientIP: DWord; LoggedAs: String): Integer;
var
i: Integer;
begin
Result := -1;
SessionLock.Enter;
try
with SessionList do
for i:= 0 to Count - 1 do
if (DWord(Objects[i]) = ClientIP) and (Items[i] = LoggedAs) then
begin
Result := i;
Break;
end;
finally
SessionLock.Leave;
end;
end;
//добавление инф-ции о новой уник.сессии в список акт.сессий
function AddSession(ClientIP: DWord; LoggedAs: String): Integer;
var
i: Integer;
begin
Result := -1;
SessionLock.Enter;
try
with SessionList do
for i:= 0 to Count - 1 do
if (DWord(Objects[i]) = ClientIP) and (Items[i] = LoggedAs) then
begin
Result := i;
Break;
end;
if Result = -1 then
begin
i := IndexOfObject(TObject(nil));
if i = -1 then
i := AddObject(LoggedAs, Pointer(ClientIP))
else
begin
Items[i] := LoggedOn;
Objects[i] := Pointer(ClientIP);
end;
end;
finally
SessionLock.Leave;
end;
end;
//удаление инф-ции о существ.уник.сессии из списока акт.сессий
function RemoveSession(ClientIP: DWord; LoggedAs: String): Integer;
var
i: Integer;
begin
Result := -1;
SessionLock.Enter;
try
with SessionList do
for i:= 0 to Count - 1 do
if (DWord(Objects[i]) = ClientIP) and (Items[i] = LoggedAs) then
begin
Result := i;
Objects[i] := nil;
Break;
end;
finally
SessionLock.Leave;
end;
end;
в момент, когда произошел новый коннект и юзер запросил вход под логином AUserName, делаем :
if AddSession(RemoteUserIP, AUserName) = -1 then
разрыв_соединения
в момент, когда юзер с таким-то IP и логином AUserName завершает сессию, делаем :
if RemoveSession(RemoteUserIP, AUserName) <> -1 then
разрыв_соединения
Shaman O Mega (2003-10-30 09:33:00) [2]
ну не совсем, я был не до конца уверен.
просто похоже я и действительно пытаюсь дорогими средствами получить надёжный код, но всё равно хочиться :). я просто просил помочь а не отговарить меня и ставить на путь истинный, здесь похоже всех больше интересует оптимизация...
:)
Digitman (2003-10-30 09:29:00) [3]
> Shaman O Mega
видно, я сделал для тебя шокирующее открытие по поводу момента создания треда)
Shaman O Mega (2003-10-30 09:27:00) [4]
всем спасибо
Digitman (2003-10-30 09:25:00) [5]
> Shaman O Mega
> на каждый конект тред создаётся только при получении данных
ничего подобного !
тред у тебя создается сразу после установления коннекта, автоматически (еще ДО того момента как клиент соизволит что-то прислать !!), и ассоциируется с данным коннектом в кач-ве транспортноготреда.
> защититься я пытаюсь от одновременного подключения с одного
> ip или с одним логином.
это не ресурс. это - логика ! а ресурс-то собственно какой ? область памяти или что ?
Reindeer Moss Eater (2003-10-30 09:24:00) [6]
ты хочешь сказать, что для синхронизации между тредами такая техника не подойдёт?
Подойдет-неподойдет это лирика.
Для синхорнизации потоков одного процесса разумеется можно использовать и события и семафоры и мьютексы.
Вопрос в стоимости такого решения.
Shaman O Mega (2003-10-30 09:19:00) [7]
на каждый конект тред создаётся только при получении данных, в том то и проблемма
а защититься я пытаюсь от одновременного подключения с одного ip или с одним логином.
Digitman (2003-10-30 09:17:00) [8]
> Shaman O Mega
какой конкретно ресурс ты пытаешься защитить таким образом от одновременного использования ?
Digitman (2003-10-30 09:14:00) [9]
> Shaman O Mega
> Не межпроцессной а межтредной.
для межтредной синхронизации в контексте одного и того же процесса малоразумно и вряд ли обосновано использование объектов МЕЖпроцессной синхронизации.. в большинстве случаев вполне достаточно использование крит.секций, это гораздо эффективней с т.з. использования ресурсов системы и производительности приложения в целом
у тебя на каждый коннект сколько тредов создается ?
Shaman O Mega (2003-10-30 09:09:00) [10]
ты хочешь сказать, что для синхронизации между тредами такая техника не подойдёт?
Reindeer Moss Eater (2003-10-30 09:09:00) [11]
Нет, как раз межпроцессной.
Shaman O Mega (2003-10-30 09:07:00) [12]
Не межпроцессной а межтредной.
Флуда я не боюсь, сервер у меня пока небольшой и ориентированный на публику которой можно по голове настучать в случае чаво...
Reindeer Moss Eater (2003-10-30 09:05:00) [13]
то ничего для меня страшного не произойдёт, пусщай висит, мне он не мешает.
Он будет открывать соединения с твоим сервером пока у тебя на сервере не кончатся ресурсы.
А так ничего сташного.
Digitman (2003-10-30 09:05:00) [14]
> Shaman O Mega
мне все равно непонятно, на кой шут здесь объект межпроцессной синхронизации задействован
Digitman (2003-10-30 09:03:00) [15]
такая логика сервера абсолютно незащищена от флуда
такой сервер рано или поздно рухнет, если будет осуществлена целенаправленная атака
Shaman O Mega (2003-10-30 09:02:00) [16]
Если он молчит, то ничего для меня страшного не произойдёт, пусщай висит, мне он не мешает. Главное что для начала работы ему всё равно нужно ввести логин и пароль, пока он не работает мне на него плевать...
Digitman (2003-10-30 08:59:00) [17]
> если подключился то можно и отключить
а если клиент подключился и "молчит" ?
ну удаленный IP-адрес ты определишь, положим, в момент коннекта ... а логин, под которым пользователь пытается начать сессию инф.обмена ? Он же молчит !? Что, соединение так и будет активным ? По какому признаку ты определишь, что этот тот же самый клиент, который ранее открыл сессию под каким-то логином ?
Shaman O Mega (2003-10-30 08:50:00) [18]
если подключился то можно и отключить. Этот код, в любом случае, может пройти только у одного клиента.
Digitman (2003-10-30 08:39:00) [19]
> Shaman O Mega
бестолковый код.
противоречит твоим же изначальным условиям
в момент выполнения CreateMutex() значение переменной AUserName чему равно ? откуда оно взялось ? клиент прислал ? значит он уже подключился ? а нахрена тогда мьютекс этот, если клиент уже подключился ?!
Shaman O Mega (2003-10-30 08:36:00) [20]
Можно иметь структуру, но она не гарантирует исключения конфликтов...