Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
14-1124434416
Jeer
2005-08-19 10:53
2005.09.11
Влияет ли фамилия на принципы ? :)


1-1124202235
lox
2005-08-16 18:23
2005.09.11
Как узнать: окно поверх других или нет, если есть хендел?


1-1124634052
OldNaum
2005-08-21 18:20
2005.09.11
Менеджмент сервиса


4-1121870239
Profik
2005-07-20 18:37
2005.09.11
Прога в трее


14-1124304243
Piter
2005-08-17 22:44
2005.09.11
Помогите плиз с C





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский