Форум: "Начинающим";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];
ВнизПосылка в нить указателя на выделенную память. Найти похожие ветки
← →
Riply © (2007-01-31 16:26) [0]Здравствуйте !
Пытаюсь следующим способом отправлять и принимать сообщения в нити:
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;
Корректен ли такой способ ? Если да, то как
"посылатели" (их может быть много)
могут узнать, чт мы уже перестали принимать сообщения
и находимся в процессе завершения нити ?
← →
Сергей М. © (2007-01-31 16:36) [1]
> Корректен ли такой способ ?
Нет, не корректен.
Необходим объект синхронизации типа mutex
← →
Riply © (2007-01-31 16:51) [2]> [1] Сергей М. © (31.01.07 16:36)
>Необходим объект синхронизации типа mutex
А без синхронизации возможно это реализовать ?
← →
Ega23 © (2007-01-31 16:54) [3]Я бы входные данные в поток через критическую секцию сделал, а выходное событие из потока - именно как событие определил и через synchronize выполнил.
← →
Ega23 © (2007-01-31 16:55) [4]Хотя нет, synchronize тут может не прокатить... Они же параллельно начнут исполняться...
← →
Сергей М. © (2007-01-31 17:07) [5]
> А без синхронизации возможно это реализовать ?
Можно, но при твоих требованиях асинхронности отправки/доставки сообщений это будет крайне ненадежно с т.з. утечек памяти, которые тебя волнуют.
← →
sniknik © (2007-01-31 17:28) [6]перед тем как послать сообщение на завершение потока (так понимаю у тебя так, посылается 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;
да и все. а вот обнуление и посылку, можно синхронизировать, или в критической секции... да и то, только если посылка и обнуление у тебя в разных потоках будут. на случай если обнуление придется на середину операции посылки (после проверки), только тогда можеш потерять выделенное.
← →
Riply © (2007-01-31 17:37) [7]> [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;
← →
Riply © (2007-01-31 17:53) [8]> [6] sniknik © (31.01.07 17:28)
>обнуляй хендл потока (ThreadID), а процедурах "посыла" проверяй если он ноль то и посылать нечего.
:) Простейшего решения не вижу :(
>а вот обнуление и посылку, можно синхронизировать,
>или в критической секции... да и то, только если посылка
>и обнуление у тебя в разных потоках будут.
>на случай если обнуление придется на середину операции посылки (после проверки),
>только тогда можеш потерять выделенное.
Обнуление и посылка будут в разных потоках
Принимающий поток - командует всем парадом . Над ним стоит только User :)
Наверное попробую использовать критические секции.
Даже не вериться, что все так просто решается :)
Спасибо всем.
P.S. Если что не так, то снова прибегу :)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.058 c