Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с потоками

1.8K
12 апреля 2007 года
GLAGOLA
80 / / 06.11.2004
Люди ситуация такая я создаю внутри класса
Constructor TPlayer.Create;
Begin
...................
TheardData.TheardStoper := false;
THeardHandle := CreateTHread(nil,0,@TPlayer.LoopController,@TheardData,0,ThreadID);
End;
процедура самого потока:
Function TPlayer.LoopController(prm: Pointer) :Integer; //stdcall;
Var
pp : TTheardData;
Begin
pp := TTheardData(prm^);
while not pp.TheardStoper do
Begin
Sleep(10);
End;
End;

Проблема в том что когда я передаю запись(а точнее указатель на нее) в поток , а потом к ней обращаюсь(внутри потока), запись содержит совсем не то что должна, хотя данные нигде в коде после запуска потока не меняются, в приведенном куске кода поток почемуто сразу завершает работу, хотя должен работать бесконечно т.к. TheardData.TheardStoper = false;, а на самом деле это поле равно тру когда обращаешься к нему из потока, что делать? уже замучался (
303
13 апреля 2007 года
makbeth
1.0K / / 25.11.2004
Так работать не будет. Ты передаешь в процедуру создания потока указатель на метод класса (@TPlayer.LoopController), что является ошибкой. Твой метод LoopController на самом деле выглядит следующим образом (поскольку является методом класса):
 
Код:
procedure TPlayer.LoopController(Self: TPlayer; prm: Pointer)
begin
     // ...
end;
Необходимо передавать только указатель на обычную процедуру.
Варианты решения:
1. Создать обычную процедуру (ИМХО, геморный вариант):
Код:
constructor TPlayer.Create
begin
    //...
    ThreadData.ThreadStoper:=false;
    ThreadData.Player:=Self; // это поле необходимо добавить
    ThreadHandle:=CreateThread(nil, 0, @ExtLoopController, @ThreadData, 0, ThreadID);
end;

procedure ExtLoopController(prm: Pointer); stdcall;
begin
    TThreadData(prm^).Player.LoopController(prm);
end;

function TPlayer.LoopController(prm: Pointer) :Integer;
var pp : TTheardData;
begin
    pp := TTheardData(prm^);
    while not pp.TheardStoper do
    begin
        Sleep(10);
    end;
end;
2. Написать обертку вокруг TPlayer c помощью наследника TThread:
Код:
type
    TPlayerWrapper = class (TThread)
    private
        player: TPlayer;
    protected
        procedure Execute; override;
    public
        constructor Create(p: TPlayer);
    end;

constructor TPlayerWrapper.Create(p: TPlayer);
begin
    player:=p;
end;

procedure TPlayerWrapper.Execute;
begin
    while not Terminated do
        player.LoopController;  
    end;
end;
3. Унаследовать TPlayer от TThread:
 
Код:
type
     TPlayer = class (TThread)
     // ...
     protected
          procedure Execute; // это и есть LoopController
     // ...
     end;
Если у тебя TPlayer ни от чего не наследуется, то, ИМХО, самый правильный вариант - третий.
Удачи.
1.8K
13 апреля 2007 года
GLAGOLA
80 / / 06.11.2004
А в последнем случае как быть с запуском и созданием нового потока, у меня просто свои собственые Create и Destroy?
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог