![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
api-потоки, создание-разрушение [D6, WinXP]
Незнайка Винидиктович © (2009-03-29 18:25:00)Вот такая проблема случилась: Пишу подобие сокс5-сервера, с сипользование winapi-потоков, т.е. при старте запускаеться отдельный поток в котором крутиться бесконечный цикл с Accept, и как только есть подключившийся сокет, он создает поток и передает этот сокет туда... Так вот странность какая, что вродебы никаких общих переменных нету, никакой синхронизации нету(за её ненадобностью), т.е. все потоки существуют отдельно друг от друга. Так вот откудато берется ошибка памяти ((
В потоке примерно вот такая штука крутиться:
while True do
begin
FD_Zero(FDSet);
FD_Set(srv_sock,FDSet);
//åñëè åñòü êëèåíò, òî ïåðåäàåì ñîêåò â êëèåíòñêèé ïîòîê
Select(0,@FDSet,nil,nil,@timeout);
if FD_IsSet(srv_sock,FDSet) then
begin
accepted_sock:=Accept(srv_sock,@Addr,@addr_size);
CreateThread(nil, 0, @cli_thread, pointer(accepted_sock), 0, h);
end;
end;
Так вот кстати, как правельно разрушать потоки???
изнутри ExitThread(0); недостаточно? или как это правельно вообще делаеться?
Незнайка Винидиктович (2009-04-01 11:53:00) [41]
> > из предложенных двух примеров не видно где утечка ?В них
> при IsMultiThread=True утечки нет.
Ну так я там использую бегинТред, значит IsMultiThread=True, следовательно утечки не должнобыть по вашим словам, но тем не мение...
Сергей М. (2009-04-01 09:31:00) [42]
> это не как не повлият на работу потока ?
Никак.
> из предложенных двух примеров не видно где утечка ?
В них при IsMultiThread=True утечки нет.
Незнайка Винидиктович (2009-04-01 07:57:00) [43]т.е. из предложенных двух примеров не видно где утечка ?
Незнайка Винидиктович (2009-04-01 07:56:00) [44]
> > > почему такая разница между двумя примерами?Утечка не
> здесьТак а где если не здесь, все что есть в этих двух вариантах
> все тут...
Вопрос так и не нашёл ответа ? )
Незнайка Винидиктович (2009-04-01 07:54:00) [45]
> Не надо - не следи, никто не заставляет.Получил хэндл, тут
> же закрыл его и забыл про него как страшный сон)
Т.е. можно закрыть хедл и работать в потоке дальше, это не как не повлият на работу потока ?
> > через 12K отработавших потока
> > через каждые 1К отработавших
> потокаКак ты узнал что они отработали ?У тебя ж никакой
> синхронизации нет , "за ненадобностью" ..
Узнал смотря в диспетчер задач и в дебаггер в самой делфи, это не достоверно?
Сергей М. (2009-03-31 08:15:00) [46]
> Что за всеми потоками следить чтоли?
>
Не надо - не следи, никто не заставляет.
Получил хэндл, тут же закрыл его и забыл про него как страшный сон)
> через 12K отработавших потока
> через каждые 1К отработавших потока
Как ты узнал что они отработали ?
У тебя ж никакой синхронизации нет , "за ненадобностью" ..
Незнайка Винидиктович (2009-03-31 04:01:00) [47]
> > изнутри никак чтоли?Чтоли
Что из нутри никак это плохо (( Что за всеми потоками следить чтоли?
> > почему такая разница между двумя примерами?Утечка не здесь
Так а где если не здесь, все что есть в этих двух вариантах все тут...
DVM (2009-03-30 22:41:00) [48]
> Т.е. EndThread(0); в потоке не достаточно? Нужно обязательно
> закрывать хедл снаружи? изнутри никак чтоли?
Поток он сам по себе, а его хендл сам по себе. Поток ты уничтожил, но хендл надо закрыть CloseHandle()
Сергей М. (2009-03-30 20:53:00) [49]
> изнутри никак чтоли?
Чтоли
> почему такая разница между двумя примерами?
Утечка не здесь
Незнайка Винидиктович (2009-03-30 18:48:00) [50]
> Т.е. EndThread(0); в потоке не достаточно? Нужно обязательно
> закрывать хедл снаружи? изнутри никак чтоли?
Даже если так то, почему такая разница между двумя примерами?
Незнайка Винидиктович (2009-03-30 18:36:00) [51]
> Утечка происходит как минимум из-за незакрытия тобой хэндлов
> создаваемых потоков.
Т.е. EndThread(0); в потоке не достаточно? Нужно обязательнозакрывать хедл снаружи? изнутри никак чтоли?
Сергей М. (2009-03-30 17:45:00) [52]
> Незнайка Винидиктович (30.03.09 17:08) [43]
Утечка происходит как минимум из-за незакрытия тобой хэндлов создаваемых потоков.
> buf:=IntToStr(n);
>
Вот как раз эти граблища рано или поздно больно хлобыстнули бы тебя, если бы IsMultiThread был равен False
DVM (2009-03-30 17:36:00) [53]
> Теперь надо найти из-за чего увеличиваеться(и потом не возвращается
> обратно) размер приложения в памяти.
Ты хендлы закрываешь?
BeginThread возвращает хэндл, какова его дальнейшая судьба у тебя?
Незнайка Винидиктович (2009-03-30 17:08:00) [54]Люди! Списибо с параметрами теперь все ок!
Теперь надо найти из-за чего увеличиваеться(и потом не возвращается обратно) размер приложения в памяти.
Зделал просто ради экспиремента:
function func(param: pointer): integer;
var
n: integer;
begin
n:=integer(param);
EndThread(0);
end;
.......
for t:=0 to 1000 do BeginThread(nil, 0, @func, pointer(t), 0, h);
Потоки рождаються и умирают нормально. Но вот примерно через 12Kотработавших потоков размер памяти увеличиваеться на 4КБ, нормально это или нет(тупо незнаю из-за малого опыта программирования)???
А вот немного переделал, тоже ради экспиримента:
function func(param: pointer): integer;
var
n: integer;
buf: string;
begin
n:=integer(param);
buf:=IntToStr(n);
EndThread(0);
end;
..........
for t:=0 to 1000 do BeginThread(nil, 0, @func, pointer(t), 0, h);
Так вот теперь через каждые 1Котработавших потока, размер увеличиваеться на 16КБ, что это значит?
Извините, если это откровенная глупость...
Вариант (2009-03-30 10:37:00) [55]
> Незнайка Винидиктович (30.03.09 10:21) [39]
> accepted_sock:=Accept(srv_sock,@Addr,@addr_size);
> BeginThread(nil, 0, @cli_thread, pointer(accepted_sock),
> 0, h);
>
> а в потоке так:
>
> procedure cli_thread(param: pointer); stdcall;
> var
> cli_sock: integer;
> ......
> begin
> cli_sock:=integer(param);
> ......
>
>
> так вот работало с CreateThread. с бегинтред нихочет, даже
> делал по ману через указатель и передачу адреса, всеравно
> нето (
function cli_thread(param: pointer):Integer; - A stdcall надо убрать;
Смотрим хелп по BeginThread
type TThreadFunc = function(Parameter: Pointer): Integer;
Сергей М. (2009-03-30 10:34:00) [56]
> procedure cli_thread(param: pointer); stdcall;
function cli_thread(hClientSocket: TSocket): Integer; //никаких stdcall !!
var
cli_sock: TSocket;
begin
cli_sock := hClientSocket;
..
end;
Незнайка Винидиктович (2009-03-30 10:22:00) [57]т.е. в cli_sockнето значение получаеться
Незнайка Винидиктович (2009-03-30 10:21:00) [58]
accepted_sock:=Accept(srv_sock,@Addr,@addr_size);
BeginThread(nil, 0, @cli_thread, pointer(accepted_sock), 0, h);
а в потоке так:
procedure cli_thread(param: pointer); stdcall;
var
cli_sock: integer;
......
begin
cli_sock:=integer(param);
......
так вот работало с CreateThread. с бегинтред нихочет, даже делал по ману через указатель и передачу адреса, всеравно нето (
Незнайка Винидиктович (2009-03-30 10:17:00) [59]
> > параметр для функции некорректно воспринимаетЧитай текст
> ошибки, вникай, исправляй ошибку
Да ошибки то как таковой нету, просто значения в поток передаеться вместо одного другое (( хотя все по мануалу делаю (
Сергей М. (2009-03-30 10:12:00) [60]
> параметр для функции некорректно воспринимает
Читай текст ошибки, вникай, исправляй ошибку