![]() |
| ||
|
|
Новости |
Поиск |
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-03-30 00:12:00) [81]
> > Я хотел бы обратить внимание, что он всегда передает указатель
> > на одну и ту же переменную, которую потом перезаписывает
> > при каждом новом коннекте.Где там указатель? Там приведение
> типа SOCKET к типу Pointer. Никакого указателя там нет.И
> ничего он не перезаписывает. Внимательно на код посмотрите.
>
Совершенно верно
мимо (2009-03-30 00:04:00) [82]
> размер приложения в процессе работы растет
Где-то утечка памяти.
мимо (2009-03-30 00:04:00) [83]
> Я хотел бы обратить внимание, что он всегда передает указатель
> на одну и ту же переменную, которую потом перезаписывает
> при каждом новом коннекте.
Где там указатель? Там приведение типа SOCKET к типу Pointer. Никакого указателя там нет.
И ничего он не перезаписывает. Внимательно на код посмотрите.
Незнайка Винидиктович (2009-03-29 23:59:00) [84]Я имел ввиду размер в памяти... (
> > мимо (29.03.09 22:36) [5]> > > > а это по твоему не
> общая: accepted_sock> > В коде выше - не общая.неправда,
> ты передаешь указатель в поток на переменную, дальнейшая
> судьба которой в основном потоке неизвестна (по крайней
> мере из приведенного кода)
так там все просто происходит
localpar:=lpParam;
т.е. легким движением руки она превращаеться в локальную переменную
Незнайка Винидиктович (2009-03-29 23:56:00) [85]Но встал другой вопрос. С потоками все впорядке, создаються-завершаютьсьяс все ок, но вот размер приложения в процессе работы растет, из-за чего это может быть?
DVM (2009-03-29 23:39:00) [86]
> мимо (29.03.09 22:36) [5]
>
>
> Зачем усложнять? Он передает одну переменную, которая равна
> (по размеру) указателю (SOKET = HANDLE = LPVOID).
Можно и не усложнять. Просто так ему будет потом удобнее, если еще что то добавить в передаваемые параметры. Я хотел бы обратить внимание, что он всегда передает указатель на одну и ту же переменную, которую потом перезаписывает при каждом новом коннекте.
DVM (2009-03-29 23:37:00) [87]
> Незнайка Винидиктович (29.03.09 18:25)
Еще, ты решил использовать CreateThread вместо BeginThread, надеюсь, не забыл про выставление флага IsMultiThread := TRUE;
DVM (2009-03-29 23:33:00) [88]
> > мимо (29.03.09 22:36) [5]
Как только произойдет ВТОРОЙ коннект к серверу, значение этой переменной будет переписано новым значением и кирдык.
DVM (2009-03-29 23:30:00) [89]
> мимо (29.03.09 22:36) [5]
>
>
> > а это по твоему не общая: accepted_sock
>
> В коде выше - не общая.
неправда, ты передаешь указатель в поток на переменную, дальнейшая судьба которой в основном потоке неизвестна (по крайней мере из приведенного кода)
Незнайка Винидиктович (2009-03-29 23:14:00) [90]ЛЮДИ! всем спасибо за ответы, проблема обнаружена!
Это было просто переполнение буфера, в самом клиентском потоке ))
Ещё раз всем спасибо!
Незнайка Винидиктович (2009-03-29 22:51:00) [91]
> > откудато берется ошибка памяти
>
>
> Она "берется" из 17-й строки в твоем коде
хм. в представленом мной коде всего 13 строк.
> > изнутри ExitThread(0); недостаточно?
>
> Достаточно.
> Иногда даже излишне.
Спасибо за ответ! )
> а это по твоему не общая: accepted_sock
В данном случае accepted_sock не общая, помойму вы что-то путаете...
> > Вот такая проблема случилась
>
> А в каком месте ошибка то происходит?
Вот даже и незнаю, нету ни обших переменных ничего такого что должно было бы её вызвать и как оказалось завершаю потоки(ExitThread(0);) тоже правельно, но она подло откудато вылезает. Вылетает она в разных местахвсегда, как не пытался дебагить, ничего не получилось, да и все ещё ослажняеться тем, что потоков несколько... а вообще откуда она может взяться если нету общих ресурсов ?
Я бы сюда полный листинг вывел, да пишет что ограничение по символам ((
мимо (2009-03-29 22:36:00) [92]
> а это по твоему не общая: accepted_sock
В коде выше - не общая.
> Тебе делать надо как то так:
Зачем усложнять? Он передает одну переменную, которая равна (по размеру) указателю (SOKET = HANDLE = LPVOID).
> Вот такая проблема случилась
А в каком месте ошибка то происходит?
DVM (2009-03-29 22:18:00) [93]
>
> Незнайка Винидиктович (29.03.09 18:25)
Тебе делать надо как то так:
ClientSocket := accept(ListenSocket, nil, nil);
if ClientSocket <> INVALID_SOCKET then
begin
New(Info);
Info^.Socket := ClientSocket;
hClientThread := BeginThread(nil, 0, @SocketThread, Info, 0, ThreadId);
....
где Info: PThreadData;
ThreadData = record
Socket: TSocket;
.....
end;
PThreadData = ^ThreadData;
Сергей М. (2009-03-29 21:25:00) [94]
> синхронизации нету(за её ненадобностью)
Смелое заявление)
DVM (2009-03-29 21:19:00) [95]
> вродебы никаких общих переменных нету
а это по твоему не общая: accepted_sock
Сергей М. (2009-03-29 19:42:00) [96]
> откудато берется ошибка памяти
Она "берется" из 17-й строки в твоем коде
> изнутри ExitThread(0); недостаточно?
Достаточно.
Иногда даже излишне.