Сквозняк писал(а):ssnakess писал(а):Из этого я понял. что Вы предлагаете не только в пишущем потоке ставить IsBusy в false, но и уведомлять еще когото.
кого?
Ну да. Если не надеетесь на потокобезопасность своего кода, то всегда можно завести внешнего бюрократа, которому будете оставлять заявки и получать или не получать разрешение на действие. Это займёт лишнее время, потому обращаться к нему нужно только когда велика вероятность его положительного ответа. Ну вот как-то так:
- Код: Выделить всё
if not fLog.IsBusy Then if bjurokrat1(nomer_potoka) Then
Begin
fLog.IsBusy:=true;
fLog.Messages.Append(msg);
uvedomlenie_bjurokratu1(nomer_potoka);
fLog.IsBusy:=false;
вот так понятно что Вы имели ввиду
вопрос откуда я возьму nomer_potoka?
т.е. я должен же его гдето взять в потоке ожидающем "свободного" буффера.
наверное это или случайное число (что хреново), или я где-то должен его "попросить", т.е. у такогож "бюрократа2"
а если есть "бюрократ2", у которого два потока одновременно попросят "номерок в очереди", то 100% могут получить одинаковый.
т.е. Ваша идея понятна, но грабли теже - несколько потоков пишут и/или просят данные у одного супер-потока
и еще есть нюанс, ИМХО, вот так:
- Код: Выделить всё
if not fLog.IsBusy Then if bjurokrat1(nomer_potoka) Then
Begin
fLog.IsBusy:=true;
fLog.Messages.Append(msg);
uvedomlenie_bjurokratu1(nomer_potoka); // вот тут может быть засада не маленькая
fLog.IsBusy:=false;
нельзя делать, ибо при вызове из двух разных потоков этого кода на выполнение, не известно какой мусор будет в стеке для переменной вот тут
- Код: Выделить всё
procedure uvedomlenie_bjurokratu1(nomer_potoka: longint); // переменная nomer_potoka хранится в стеке при вызове процедуры
begin
zajavki2[nomer_potoka]:=0;
zajavki1[nomer_potoka]:=0;
end;
дабы избежать приколов реализации компилятора - код потока должен быть для каждого свой, Вы можете использовать переменные потока и передавать потоку ссылку на внешнюю переменную, и уже внутри кода потока ею "злодействовать".
т.е. на этом же примере
- Код: Выделить всё
if not fLog.IsBusy Then if bjurokrat1(nomer_potoka) Then
Begin
fLog.IsBusy:=true;
fLog.Messages.Append(msg);
zajavki2[nomer_potoka]:=0;
zajavki1[nomer_potoka]:=0;
fLog.IsBusy:=false;
[/code]
Вы поняли о чем я?
да, это фигово ибо дублируется код, но тут лучше сделать так, чем получить непонятки из-за непойми чего храянщегося в стеке при вызове процедуры из разных потоков.