Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Синхронизация потоков [D7, WinXP]


Николас ©   (2006-08-01 02:08:00) 

Помогите разобраться с проблемой, есть несколько потоков в которых выполняется какие-то действия, в потокал выводятся данные в лог подобным образом:


procedure WriteLog(S:String);
begin
 Memo1.Lines.Text := s ;
end;


но при одновременной попытке нескольких потоков записать лог, приложение виснет. Пытался решить эту проблему с помощью критических секций, так:


var
CriticalSection: TCriticalSection ;
...  
CriticalSection := TCriticalSection.Create;
...
procedure WriteLog(S:String);
begin
 CriticalSection.Enter ;
 Memo1.Lines.Text := s ;
 CriticalSection.Leave ;
end;


но проблема осталась, приложение зависает. если закомментировать строку "Memo1.Lines.Text := s ;" то все работает нормально, зависаний небыло... Посоветуйте что можно сделать.


Сергей М.   (2006-08-01 09:43:00) [1]


> Николас   (01.08.06 09:38) [6]
>
> Как я только не догадался


Действительно, и так не догадался и эдак не догадался)
Есть же исх.текст TThread, его и следовало бы в  1-ю очередь посмотреть на предмет как это реализовано у самого Борланда ..


Николас   (2006-08-01 09:38:00) [2]

Как я только не догадался :) Спасибо огромное!!! Вечером проверю и скажу результат, думаю прокатит :)


Сергей М.   (2006-08-01 09:34:00) [3]


> Николас   (01.08.06 09:25) [3]


const
 TM_LOG = WM_USER + 100; //константа 100 выбрана от фонаря

type
 
TMyForm = class(TForm)
..
 procedure MsgThreadLog(var Message: TMessage); message TM_LOG;
..
end;

..

procedure TMyForm.MsgThreadLog(var Message: TMessage);
begin
 Mem1.Lines.Add(PChar(Message.wParam));
end;

function Process(Parameter : Pointer) : Integer;
var
 s: String;
begin
...
 s := 'SomeText';
 SendMessage(MyForm.Handle, TM_LOG, wParam(PChar(s)), 0);
...
end;


Slym   (2006-08-01 09:28:00) [4]

SendMessage ?


Николас   (2006-08-01 09:25:00) [5]

Спасибо за ответы, про Synchronize знаю, его бы и использовал если бы у меня был TThread :) Но дело в том что потоки запускаются следующим образом:  
BeginThread(nil, 0, Addr(Process), nil, 0, tid);
...
function Process(Parameter : Pointer) : Integer;
begin
...
end;


Slym   (2006-08-01 06:16:00) [6]

Николас   (01.08.06 2:08)
procedure WriteLog(S:String);
begin
CriticalSection.Enter ;
Memo1.Lines.Text := s ;
CriticalSection.Leave ;
end;

Все равно не защитил главный поток от дочерних :(
Только synchronize

procedure Thread1.WriteLog(const S:String);
begin
 FS:=s;
 synchronize(DoWriteLog)
end;

procedure Thread1.DoWriteLog;
begin
 Form1.Memo1.Lines.Add(FS);
end;


Eraser   (2006-08-01 02:17:00) [7]

> [0] Николас   (01.08.06 02:08)


> Memo1.Lines.Text := s ;

1. странный способ занасить данные в Log.
2. к VCL объектам нельзя обращаться из доп. потоков. См. в сторону synchronize.


Наверх

Титульная страница Поиск, карта сайта Написать письмо