![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Посылка в нить указателя на выделенную память.
Riply © (2007-01-31 16:26:00)Здравствуйте !
Пытаюсь следующим способом отправлять и принимать сообщения в нити:
function PostMessTest(const ThreadID: DWord): Boolean;
var
cbSize : integer;
pData : Pointer;
begin
cbSize := 256;
pData := GetMemory(cbSize);
// Заполняем
Result := PostThreadMessage(ThreadID, WM_TEST_MESSAGE, cbSize, LPARAM(pData));
if not Result then FreeMem(pData);
end;
procedure ReceiveMessTest;
var
aMsg : TMsg;
begin
while GetMessage(aMsg, INVALID_HANDLE_VALUE, 0, 0) do
case aMsg.message of
WM_TEST_MESSAGE:
try
// Читаем
finally
FreeMem(Pointer(aMsg.lParam));
end;
WM_BLA_BLA: Break;
end;
// Долго завершаем нить, а сообщения все идут и идут :)
end;
Корректен ли такой способ ? Если да, то как
"посылатели" (их может быть много)
могут узнать, чт мы уже перестали принимать сообщения
и находимся в процессе завершения нити ?
Riply (2007-01-31 17:53:00) [1]> [6] sniknik © (31.01.07 17:28)
>обнуляй хендл потока (ThreadID), а процедурах "посыла" проверяй если он ноль то и посылать нечего.
:) Простейшего решения не вижу :(
>а вот обнуление и посылку, можно синхронизировать,
>или в критической секции... да и то, только если посылка
>и обнуление у тебя в разных потоках будут.
>на случай если обнуление придется на середину операции посылки (после проверки),
>только тогда можеш потерять выделенное.
Обнуление и посылка будут в разных потоках
Принимающий поток - командует всем парадом . Над ним стоит только User :)
Наверное попробую использовать критические секции.
Даже не вериться, что все так просто решается :)
Спасибо всем.
P.S. Если что не так, то снова прибегу :)
Riply (2007-01-31 17:37:00) [2]> [5] Сергей М. © (31.01.07 17:07)
> крайне ненадежно с т.з. утечек памяти, которые тебя волнуют.
А утечки возможны только в "// Долго завершаем нить, а сообщения все идут и идут :)" ?
Или еще где-то ?
Если только здесь, то можно попробовать как-то пресечь отправку сообщений (тот же Mutex)
типа:
var
LastTest: Boolean;
case aMsg.message of
WM_TEST_MESSAGE:
try
// Читаем
if LastTest then
begin
while PeakMessage() do
begin
// Освобождаем память
end;
Exit;
end;
finally
FreeMem(Pointer(aMsg.lParam));
end;
WM_BLA_BLA:
begin
LastTest := True;
// CreateMutex
end;
end;
sniknik (2007-01-31 17:28:00) [3]перед тем как послать сообщение на завершение потока (так понимаю у тебя так, посылается WM_BLA_BLA) обнуляй хендл потока (ThreadID), а процедурах "посыла" проверяй если он ноль то и посылать нечего.
function PostMessTest(const ThreadID: DWord): Boolean;
var
pData : Pointer;
begin
if ThreadID <> 0 then begin
pData := GetMemory(256);
// Заполняем
Result:= PostThreadMessage(ThreadID, WM_TEST_MESSAGE, cbSize, LPARAM(pData));
if not Result then FreeMem(pData);
end;
end;
да и все. а вот обнуление и посылку, можно синхронизировать, или в критической секции... да и то, только если посылка и обнуление у тебя в разных потоках будут. на случай если обнуление придется на середину операции посылки (после проверки), только тогда можеш потерять выделенное.
Сергей М. (2007-01-31 17:07:00) [4]
> А без синхронизации возможно это реализовать ?
Можно, но при твоих требованиях асинхронности отправки/доставки сообщений это будет крайне ненадежно с т.з. утечек памяти, которые тебя волнуют.
Ega23 (2007-01-31 16:55:00) [5]Хотя нет, synchronize тут может не прокатить... Они же параллельно начнут исполняться...
Ega23 (2007-01-31 16:54:00) [6]Я бы входные данные в поток через критическую секцию сделал, а выходное событие из потока - именно как событие определил и через synchronize выполнил.
Riply (2007-01-31 16:51:00) [7]> [1] Сергей М. © (31.01.07 16:36)
>Необходим объект синхронизации типа mutex
А без синхронизации возможно это реализовать ?
Сергей М. (2007-01-31 16:36:00) [8]
> Корректен ли такой способ ?
Нет, не корректен.
Необходим объект синхронизации типа mutex