Как реализовать обработку информации одновременно несколькими потоками

 

 

Запускайте Delphi. Итак, наша программа будет представлять из себя форму с двумя edit'ами и кнопкой. Добавьте их на форму.

 

При нажатии на кнопку будут осуществляться некоторые долгие вычисления. Если бы мы не использовали потоки, то, пока эти вычисления не закончатся, делать мы ничего бы не смогли. Надо было бы ждать. Но, так как потоки у нас будут, то во время долгих вычислений можно будет что-нибудь вводить во второй edit (он, собственно, только для этого и существует). В первый же edit наш поток будет выводить некоторые промежуточные результаты своей работы.

 

 Как создавать потоки без класса TThread?

 

Примечание от Jin X

Программа не работает. Запускаю, жму Button1, счётчик покрутится полсекунды и всё. Кстати, у procedure incedit1; stdcall; не должно быть параметра типа pointer? Но даже и с ним не пашет. А вот если после i := i + 1; поставить Sleep(10), то будет работать. Вот только не понятно почему. Может, из-за того, что нет синхронизации?

Ниже приведено две таблицы кода.

Поток с доступом к глобальной переменной основной программы

 

Автор: Xavier Pacheco

 

Code:

unit Main;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls;

 

type

TMainForm = class(TForm)

  Button1: TButton;

  procedure Button1Click(Sender: TObject);

private

  { Private declarations }

public

  { Public declarations }

end;

 

var

MainForm: TMainForm;

 

implementation

 

{$R *.DFM}

 

{ NOTE: Change GlobalStr from var to threadvar to see difference }

var

//threadvar

GlobalStr: string;

 

type

TTLSThread = class(TThread)

private

  FNewStr: string;

protected

  procedure Execute; override;

public

  constructor Create(const ANewStr: string);

end;

 

procedure SetShowStr(const S: string);

begin

if S = '' then

  MessageBox(0, PChar(GlobalStr), 'The string is...', MB_OK)

else

  GlobalStr := S;

end;

 

constructor TTLSThread.Create(const ANewStr: string);

begin

FNewStr := ANewStr;

inherited Create(False);

end;

 

procedure TTLSThread.Execute;

begin

FreeOnTerminate := True;

SetShowStr(FNewStr);

SetShowStr('');

end;

 

procedure TMainForm.Button1Click(Sender: TObject);

begin

SetShowStr('Hello world');

SetShowStr('');

TTLSThread.Create('Dilbert');

Sleep(100);

SetShowStr('');

end;

 

end.

 

Помещение формы в поток

 

Delphi имеет в своем распоряжении классную функцию, позволяющую сделать это:

Code:

procedure WriteComponentResFile(const FileName: string;

Instance: TComponent);

 

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

Code:

function ReadComponentResFile(const FileName: string;

Instance: TComponent): TComponent;

 

Потоки и DLL

  

Приведенный ниже текст подразумевает, что вы обладаете базовыми знаниями о принципе работы потоков и умеете создавать DLL.

 Техническая сторона вопроса будет сфокусирована на потоках и функции DllEntryPoint. Функция DllEntryPoint не должна объявляться в ваших Delphi DLL. Фактически, большую часть, если не всю, Delphi DLL будет правильно работать и без вашего явного объявления DllEntryPoint. Тем не менее, я включил данный совет для тех Win32-программистов, которые понимают эту функцию и хотят связать с ней свое функциональное назначение, чтобы оно являлось частью DLL. Чтобы быть более конкрентым, это будет интересно тем программистам, которые хотят вызывать одну и ту же DLL из многочисленных потоков одной программы.