Да, потоки могут изменять переменные. Переменные не принадлежат потокам. Переменные могут принадлежать объектам формы или потока, но объект потока (т. Е. Экземпляр TThread
или его потомков) отличается от потока выполнения ОС.
У объектов может быть код, который выполняется в нескольких потоках. Ваш метод TThread.Create
выполняется в контексте вызывающего его потока, который часто является вашим основным потоком. С другой стороны, метод Execute
выполняется в контексте созданного потока ОС. Но очевидно, что оба метода могут обращаться к полям объекта TThread
, так что это отвечает на вопрос, могут ли два потока ОС обращаться к одной и той же переменной.
Однако у вас возникнут проблемы с доступом к переменной формы описанным вами способом. Передача его в конструктор в качестве параметра var позволит конструктору изменить его, но, как я упоминал выше, конструктор не запускается в контексте нового потока ОС. Чтобы новый поток мог получить доступ к этой переменной, вам нужно сохранить указатель на нее, а не передавать по ссылке. Например:
type
TSteveThread = class(TThread)
private
FVariable: PInteger;
protected
procedure Execute; override;
public
constructor Create(Variable: PInteger);
end;
constructor TSteveThread.Create;
begin
inherited Create(False);
FVariable := Variable;
end;
procedure TSteveThread.Execute;
begin
// Access FVariable^ here.
end;
Создайте это так:
procedure TSteveForm.ButtonClick;
begin
TSteveThread.Create(@Self.Variable);
end;
Альтернативой является передача вместо этого ссылки на форму, а затем доступ к полю формы через эту ссылку. Например:
type
TSteveThread = class(TThread)
private
FForm: TSteveForm;
protected
procedure Execute; override;
public
constructor Create(Form: TSteveForm);
end;
constructor TSteveThread.Create;
begin
inherited Create(False);
FForm := Form;
end;
procedure TSteveThread.Execute;
begin
// Access FForm.Variable here.
end;
Создайте это так:
procedure TSteveForm.ButtonClick;
begin
TSteveThread.Create(Self);
end;
В любом случае вам необходимо принять обычные меры предосторожности при управлении одновременным доступом к данным несколькими потоками. Суть в том, что оба потока могут получить доступ к данным.
person
Rob Kennedy
schedule
04.02.2015
TThread.Create
не виртуальный. Так что лучше объявить единый стандарт акцийconstructor Create(<required params>);
и все. Напишите свой конструктор потоков, в котором есть все, что ему нужно: ни больше, ни меньше. Так будет намного проще поддерживать. - person Disillusioned   schedule 04.02.2015