Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
ВнизПередача параметра из потока Найти похожие ветки
← →
ksa2002 (2005-08-15 18:53) [0]Вопрос такой
есть процедура в главном потоке
f_main;
её вызывает поток 1-й
Synchronize(f_main);
и её вызывает поток 2-й
Synchronize(f_main);
------------------------------
можно ли сделать так
f_main (s:string);
её вызывает поток 1-й
Synchronize(f_main("1"));
и её вызывает поток 2-й
Synchronize(f_main("2"));
т.е. вызвать её с параметром?
← →
troits © (2005-08-15 19:00) [1]Нет, так явно нельзя, поскольку параметр Synchronize, TThreadMethod жестко описан как procedure of object. Для передачи параметров надо воспользоваться какой-нибудь переменной, видимой из f_main.
← →
troits © (2005-08-15 19:07) [2]Кстати, заполнение этих переменных надо "обезопасить", например, критическими секциями.
← →
ksa2002 (2005-08-15 19:17) [3]хех ...так она работает))) мне интересно была передача с параметром )
← →
Eraser © (2005-08-15 21:13) [4]ksa2002 (15.08.05 19:17) [3]
Как вариант можно использовать сообщения - 2 параметра есть как-никак.
← →
ksa2002 (2005-08-15 22:36) [5]Возникла проблема !
При создание крит секции вылетает ошибка
private
FCSBuf1 : TCriticalSection;
.................
FCSBuf1.Create;
EAccessViolation ...."ntdll.dll"
хелп ми!
← →
Eraser © (2005-08-15 22:42) [6]Не создан объект!
___
Я бы использовал RTL_CRITICAL_SECTION и ф-ии InitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection.
← →
Наиль © (2005-08-15 22:46) [7]>[5]
Кто же так создаёт объекты ?!
Смотри как надо!FCSBuf1:=TCriticalSection.Create;
← →
ksa2002 (2005-08-15 23:25) [8]ещё вопрос
два разных потока присваевают значение одной переменной
как приостоновить один потока пока не будет произведена обработка значения? (если можно с примером)
← →
Eraser © (2005-08-15 23:28) [9]ksa2002 (15.08.05 23:25) [8]
Именно для этого и созданы критические секции!
← →
ksa2002 (2005-08-15 23:34) [10]про обработку понятно
я имел ввиду что есть паблик переменная которой присваевается значение перед вызовом крит секции, но присваение не входит в крит секцию ..как в этом случаи быть? (ведь данную переменую можно затереть)
← →
Alexander Panov © (2005-08-15 23:37) [11]Может быть попробуешь по форуму поискать?
За минуту поиска находится вот такая ветка
http://delphimaster.net/view/1-1123147749/
← →
Eraser © (2005-08-15 23:39) [12]ksa2002 (15.08.05 23:34) [10]
Тогда никак! Если эта переменная не пренадлежит экземпляру наследника TThread данного потока. Если это так, то защищать ничего не надо.
Так же можно не защищать любые однобайтовые переменые.
← →
ksa2002 (2005-08-15 23:46) [13]т.е. если так
в главном потоке
public
str:string
----------------------------
поток 1-й
str:=знач1;
Synchronize(f_main);
поток 2-й
str:=знач2;
Synchronize(f_main);
---------------------------
получается что мне не надо защищать str?(в момент присвоения)
← →
Eraser © (2005-08-15 23:48) [14]ksa2002 (15.08.05 23:46) [13]
Надо!
Т.к. str - глобальная переменная! Повторюсь - защищать не надо только переменные (поля) экземпляра текущего потока.
← →
DrPass © (2005-08-15 23:50) [15]Надо. И не только в момент присвоения, поэтому самый разумный способ - перенести это присвоение в функцию f_main
← →
ksa2002 (2005-08-15 23:50) [16]вот я о том же , но как ? Есть симофоры но у меня нет примера по их использованию
← →
ksa2002 (2005-08-15 23:52) [17]
> DrPass ©
можно...т.е. это присвоение для каждой переменной, а если у меня автомат. создание потоков? но есть же другой способ
← →
Alexander Panov © (2005-08-15 23:53) [18]Ты пойми, защищаются, по-существу, не сами переменные, а код, который эти переменные использует.
← →
Alexander Panov © (2005-08-15 23:57) [19]Блин, не сидел бы сейчас за покетом, привел бы пару примеров. А вообще, примеров море, как здесь, таки в интернете. Кроме того, на сайте есть статьи по потокам.
← →
DrPass © (2005-08-16 00:03) [20]
> ksa2002 (15.08.05 23:52) [17]
Заведи локальное для потока поле с нужным значением, и устанавливай его персонально для каждого экземпляра TThread. А присвоение значения этого поля глобальной переменной вынеси в синхронизируемый код. В противном случае накладки возможны даже в случае, когда...
str:=знач1;
<в этот момент второй поток меняет значение str>
Synchronize(f_main);
← →
Eraser © (2005-08-16 00:13) [21]ksa2002
EnterCriticalSection(lpCrtlSctn);
str:=знач1;
Synchronize(f_main);
LeaveCriticalSection(lpCrtlSctn);
При загрузке приложения выполниInitializeCriticalSection(lpCrtlSctn);
← →
Defunct © (2005-08-16 03:05) [22]ksa2002 (15.08.05 23:46) [13]
> получается что мне не надо защищать str?(в момент присвоения)
Eraser © (15.08.05 23:48) [14]
> Надо!
В общем-то защищать надо, только в данном конкретном случае это ничего не даст. Т.е. если речь идет о выводе переменной на экран можем наблюдать
1
1
или
2
2
вместо
1
2
> ksa2002 (15.08.05 23:50) [16]
CriticalSection и семафоры тут не нужны, Synchronize работает по механизму "рандеву" между любым потоком и основным.
Вам нужно передавать именно переменную. Учитывая, что внутри Synchronize любой код становится потокобезопасным, т.к. исполнятся строго в основном потоке, самым лучшим выходом может быть такой:
// рисуем какую-то дополнительную процедуру, которую будем
// синхронизировать с осн. потоком.
procedure TMyThread.SyncProc;
begin
// в ней вызываем все, что надо и с любыми параметрами.
// здесь же можем безопастно менять любые глобальные переменные.
// здесь же мы можем и обращаться к VCL
f_main( 2 );
end;
procedure TMyThread.Execute;
begin
...
Synchronize( SyncProc );
...
end;
← →
ksa2002 (2005-08-16 12:11) [23]хм.... а ведь правда ....спасибо проверю :)
← →
ksa2002 (2005-08-16 16:51) [24]
> // рисуем какую-то дополнительную процедуру, которую будем
> // синхронизировать с осн. потоком.
> procedure TMyThread.SyncProc;
> begin
> // в ней вызываем все, что надо и с любыми параметрами.
> // здесь же можем безопастно менять любые глобальные переменные.
>
> // здесь же мы можем и обращаться к VCL
> f_main( 2 );
> end;
>
> procedure TMyThread.Execute;
> begin
> ...
> Synchronize( SyncProc );
> ...
> end;
Возникла следующая ошибка при вызове Synchronize( SyncProc );
There is no overloaded version of "Synchronize" that can be called with these arguments
← →
ksa2002 (2005-08-16 16:56) [25]походу TMyThread.SyncProc должна располагатся в основном потоке, не хотелось бы. Хотелось бы всё проворачивать в текущем потоке.
← →
Alexander Panov © (2005-08-16 17:03) [26]Ты бы почитал все-таки книжки, статьи и пр.
uses ...,
Unit1;
TMyThread=class(TThread)
private
FId: String;
FCounter: Integer;
procedure DoPrint;
protected
procedure Execute; override;
public
constructor Create(const aId: String);
end;
...
constructor TMyThread.Create(const aId: String);
begin
inherited Create(True);
FreeOnTerminate := True;
FId := Id;
FCounter := 0;
Resume;
end;
procedure Execute;
begin
while not Terminated do
begin
Sleep(1);
if Terminated then Break;
Inc(FCounter);
Synchronize(DoPrint);
end;
end;
procedure DoPrint;
begin
Form1.Label1.Caption := FId+":"+IntToStr(Counter);
end;
← →
Eraser © (2005-08-16 17:03) [27]ksa2002 (16.08.05 16:56) [25]
Абсолютно не важно где объявлена и реализована SyncProc. Главное чтобы это был процедурный метод без параметров.
← →
Alexander Panov © (2005-08-16 17:04) [28]В предыдущем посте читать:
вместо procedure Execute; procedure TMyThread.Execute;
вместо procedure DoPrint; procedure TMyThread.DoPrint;
← →
ksa2002 (2005-08-16 17:25) [29]
> Alexander Panov © (16.08.05 17:03) [26]
Спасибо за помощь , но вроде форум для этого и предназначен.
Информация мало. В книгах почти не описан, в инете только куски кода.Поэтому я и пытаюсь уяснить принцип работы данных вещей.
← →
Alexander Panov © (2005-08-16 17:38) [30]На этом сайте есть много занимательных и полезных статей не только о потоках.
О потоках вот эта:
http://www.delphimaster.ru/articles/panov/index.html
← →
han_malign © (2005-08-16 17:57) [31]>Eraser © (16.08.05 00:13) [21]
>.............................
>EnterCriticalSection(lpCrtlSctn);
>str:=знач1;
>Synchronize(f_main);
>LeaveCriticalSection(lpCrtlSctn);
- грубое(не сказать тупое) решение - теперь в f_main вызываем функцию потока защищенную той-же критической секцией, получаем deadlock, и долго-долго ищем почему программы зависает...
если так уж хочется синхронный метод с параметрами(см. DrPass ©(16.08.05 00:03)[20]):
type TSyncMethod = procedure(Param1: TType1;...;ParamN: TTypeN; var AResult: TTypeRes);
..............................
private
FParam1: TType1;
..............................
FParamN: TTypeN;
FResult: TTypeRes;
function SyncMethod(Param1: TType1;...;ParamN: TTypeN): AResult;
procedure _SyncMethod;
public
OnSyncMethod: TSyncMethod;
..............................
function TSMThread.SyncMethod(Param1: TType1;...;ParamN: TTypeN): TTypeRes;
begin
FParam1:= Param1;
................
FParamN:= ParamN;
Syncronise(_SyncMethod);
Result:= FResult;
end;
procedure TSMThread._SyncMethod;
begin
if(Assigned(OnSyncMethod)) then OnSyncMethod(FParam1,...,FParamN,FResult);
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.01 c