Текущий архив: 2003.12.23;
Скачать: CL | DM;
Вниз
Semaphore vs Mutex Найти похожие ветки
← →
Shaman O Mega (2003-10-29 16:01) [0]Я пишу многопоточный многопользовательский сервер, при подключении клиента я создаю семафор с его именем и ip адрессом (в одном потоке ), затем когда пользователь выходит я пытаюсь уничтожить этот семафор (это уже другой поток, но того же процесса), однако у меня ничего не получается... С мьютексами та же проблема. :) помогите дураку
← →
MBo © (2003-10-29 16:11) [1]код?
← →
Reindeer Moss Eater © (2003-10-29 16:38) [2]Если сервер один (один процесс) то зачем мьютекс?
А вообще в чем должно состоять назначение объектов синхронизации для твоего сервера?
← →
Polevi © (2003-10-29 21:11) [3]"ничего не получается", как же, очень распространенная ошибка
← →
Shaman O Mega (2003-10-30 08:11) [4]Синхронизация как я уже написал нужна для того чтобы пользователь с одним логином или ip не зашёл два раза, ситуация довольно критична, проверка и создание семафора совмещены, таким образом я не попаду в ситуацию когда произошло два соединения с одного ip(с одним loginом) и оба поймали момент, когда они ещё не появились в списках и считают оба соединания первыми... и т.д. и т.п...
Товарищи, попрошу без иронии.
MBo что значит "код?"?
← →
MBo © (2003-10-30 08:25) [5]приведи свой код, с которым не получается - наиболее важные куски
← →
Digitman © (2003-10-30 08:27) [6]
> Shaman O Mega
ни семафор ни мьютекс не поможет в решении этой задачи.
для полноценного рижекта нежелательных кл.запросов на коннект на сервере для "слушающего" гнезда нужно задействовать механизм True Conditional Acceptance и механизм Quality Of Service (на обеих сторонах потенциального соединения)
← →
Reindeer Moss Eater © (2003-10-30 08:34) [7]Даже если разруливать подключения с одного адреса на уровне приложения, то все равно зачем мьютексы семафоры и прочее?
Что, серверу нельзя иметь структуру с информацией о уже подключенных пользователях и их IP ?
← →
Shaman O Mega (2003-10-30 08:36) [8]NameMutex:=CreateMutex(NIL,False,PChar(AUserName));
if GetLastError=ERROR_ALREADY_EXISTS then
begin
AThread.Connection.WriteLn("one login - one connection");
AThread.Connection.Disconnect;
exit;
end;
if ReleaseMutex((AThread.Data as TUser).NameMutex) then
Вот код
← →
Shaman O Mega (2003-10-30 08:36) [9]Можно иметь структуру, но она не гарантирует исключения конфликтов...
← →
Digitman © (2003-10-30 08:39) [10]
> Shaman O Mega
бестолковый код.
противоречит твоим же изначальным условиям
в момент выполнения CreateMutex() значение переменной AUserName чему равно ? откуда оно взялось ? клиент прислал ? значит он уже подключился ? а нахрена тогда мьютекс этот, если клиент уже подключился ?!
← →
Shaman O Mega (2003-10-30 08:50) [11]если подключился то можно и отключить. Этот код, в любом случае, может пройти только у одного клиента.
← →
Digitman © (2003-10-30 08:59) [12]
> если подключился то можно и отключить
а если клиент подключился и "молчит" ?
ну удаленный IP-адрес ты определишь, положим, в момент коннекта ... а логин, под которым пользователь пытается начать сессию инф.обмена ? Он же молчит !? Что, соединение так и будет активным ? По какому признаку ты определишь, что этот тот же самый клиент, который ранее открыл сессию под каким-то логином ?
← →
Shaman O Mega (2003-10-30 09:02) [13]Если он молчит, то ничего для меня страшного не произойдёт, пусщай висит, мне он не мешает. Главное что для начала работы ему всё равно нужно ввести логин и пароль, пока он не работает мне на него плевать...
← →
Digitman © (2003-10-30 09:03) [14]такая логика сервера абсолютно незащищена от флуда
такой сервер рано или поздно рухнет, если будет осуществлена целенаправленная атака
← →
Reindeer Moss Eater © (2003-10-30 09:05) [15]то ничего для меня страшного не произойдёт, пусщай висит, мне он не мешает.
Он будет открывать соединения с твоим сервером пока у тебя на сервере не кончатся ресурсы.
А так ничего сташного.
← →
Digitman © (2003-10-30 09:05) [16]
> Shaman O Mega
мне все равно непонятно, на кой шут здесь объект межпроцессной синхронизации задействован
← →
Shaman O Mega (2003-10-30 09:07) [17]Не межпроцессной а межтредной.
Флуда я не боюсь, сервер у меня пока небольшой и ориентированный на публику которой можно по голове настучать в случае чаво...
← →
Reindeer Moss Eater © (2003-10-30 09:09) [18]Нет, как раз межпроцессной.
← →
Shaman O Mega (2003-10-30 09:09) [19]ты хочешь сказать, что для синхронизации между тредами такая техника не подойдёт?
← →
Digitman © (2003-10-30 09:14) [20]
> Shaman O Mega
> Не межпроцессной а межтредной.
для межтредной синхронизации в контексте одного и того же процесса малоразумно и вряд ли обосновано использование объектов МЕЖпроцессной синхронизации.. в большинстве случаев вполне достаточно использование крит.секций, это гораздо эффективней с т.з. использования ресурсов системы и производительности приложения в целом
у тебя на каждый коннект сколько тредов создается ?
← →
Digitman © (2003-10-30 09:17) [21]
> Shaman O Mega
какой конкретно ресурс ты пытаешься защитить таким образом от одновременного использования ?
← →
Shaman O Mega (2003-10-30 09:19) [22]на каждый конект тред создаётся только при получении данных, в том то и проблемма
а защититься я пытаюсь от одновременного подключения с одного ip или с одним логином.
← →
Reindeer Moss Eater © (2003-10-30 09:24) [23]ты хочешь сказать, что для синхронизации между тредами такая техника не подойдёт?
Подойдет-неподойдет это лирика.
Для синхорнизации потоков одного процесса разумеется можно использовать и события и семафоры и мьютексы.
Вопрос в стоимости такого решения.
← →
Digitman © (2003-10-30 09:25) [24]
> Shaman O Mega
> на каждый конект тред создаётся только при получении данных
ничего подобного !
тред у тебя создается сразу после установления коннекта, автоматически (еще ДО того момента как клиент соизволит что-то прислать !!), и ассоциируется с данным коннектом в кач-ве транспортного треда.
> защититься я пытаюсь от одновременного подключения с одного
> ip или с одним логином.
это не ресурс. это - логика ! а ресурс-то собственно какой ? область памяти или что ?
← →
Shaman O Mega (2003-10-30 09:27) [25]всем спасибо
← →
Digitman © (2003-10-30 09:29) [26]
> Shaman O Mega
видно, я сделал для тебя шокирующее открытие по поводу момента создания треда)
← →
Shaman O Mega (2003-10-30 09:33) [27]ну не совсем, я был не до конца уверен.
просто похоже я и действительно пытаюсь дорогими средствами получить надёжный код, но всё равно хочиться :). я просто просил помочь а не отговарить меня и ставить на путь истинный, здесь похоже всех больше интересует оптимизация...
:)
← →
Digitman © (2003-10-30 10:31) [28]
> здесь похоже всех больше интересует оптимизация
до оптимизации еще и речи не дошло) ... ты так и не сказал, какой ресурс в каком контексте-масштабе ты пытаешься защитить) ... это, видимо, великий и непостижимы секрет)
ну вот смотри, попытаюсь проиграть твою ситуацию в псевдокоде, как я ее вижу :
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
разрыв_соединения
Страницы: 1 вся ветка
Текущий архив: 2003.12.23;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.017 c