Перейти к содержанию
Fire Monkey от А до Я
  • 0

Чтение файлов в отдельной потоке.


Андрей Рулин

Вопрос

Очередная "чуча" от fmx(Delphi 10 Seattle)

Если просто читать без потока , кода работает на обоих платформах

begin
        if ThreadFile.BytesReady<=ThreadFile.Counter then
        begin
          BlockRead(FileByte,ThreadFile.Buf1,Len[4]);
          ThreadFile.Counter := 0;
          ThreadFile.BytesReady :=Len[4];
        end;
        Move(ThreadFile.Buf1[ThreadFile.Counter],GetHidBufPointer^,Len[3]);
        ThreadFile.Counter := ThreadFile.Counter + Len[3];
      end;

 

Если использовать потоки 

begin
        if ThreadFile.BytesReady=0 then
          begin
            BlockRead(FileByte,ThreadFile.Buf1,Len[4]);
            ThreadFile.BackBuf := False;
            ThreadFile.BytesReady := Len[4];
            ThreadFile.Resume;
          end;
        if ThreadFile.Counter=ThreadFile.BytesReady then
          begin
            ThreadFile.Counter := 0;
            ThreadFile.BytesReady :=0;
            ThreadFile.BackBuf := not ThreadFile.BackBuf;
            ThreadFile.Resume;
          end;
        if  ThreadFile.BackBuf then  Move(ThreadFile.Buf2[ThreadFile.Counter],GetHidBufPointer^,Len[3])
                               else  Move(ThreadFile.Buf1[ThreadFile.Counter],GetHidBufPointer^,Len[3]);
        ThreadFile.Counter := ThreadFile.Counter + Len[3];
      end;

//-------------

procedure TThreadFile.Execute;
begin
  inherited;
  while True do
    begin
      if BackBuf then BlockRead(FileByte,Buf1,Len[4])
                 else BlockRead(FileByte,Buf2,Len[4]);
      BytesReady := BytesReady + Len[4];
      Suspend;
     // Self.
    end;
end;

То в этом случае всё работает только в fmx в версии win32 . В Андройде , увы читаются нули.

 

В принципе ошибка не критичная, т.к. второй вариант в итоге не даёт приросто производительности, но в общей случае настораживает. 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0

 

Buf1,Buf2 : Array[0..13100] of byte;
FileByte        : File of byte;
Len : array[0..7] of integer
              = (26,20,26,131,13100,36,36,36);

 

Цитата

а что за конструкция while true do suspend там вообще?? 

 

В отдельном потоке читаем файл.  После каждого чтения поток "засыпает". Если у нас осталось меньше 13100 байт, опять будим поток.

Вот ещё вариант, накодил сегодня.

procedure TThreadSignal.Execute;
begin
  inherited;
  while True do
    begin
      fCompleted := False;
      Task[fi].Solve;
      fCompleted := True;
      Suspend;
    end;
end;

Тут вообще андройдовская версия намертво повисает. А под win32 всё исправно работает, производит вычисления. 

Тут идея тоже самая почти. Надо провести 4 вычисления параллельно. Потом дождаться , пока все 4 выполнятся и идти дальше. 

 

Изменено пользователем Андрей Рулин
Ссылка на комментарий
  • 0
Цитата

тут читали про Suspend ?? логично же да?

"undefined behavior within your application"  подозреваю всё же не о том, что одной платформе будет работать , а на другой "кроссплатформенная" FMX как обычно будет виснуть.

Цитата

создавать циклы, используя конструкцию TParallel.For;

Нет , в данном случае плохо.  Т.к. данная система создаёт и убивать потоки, это очень много времени занимает. 

Вот я создал даже пример https://drive.google.com/file/d/17qjew0kjq8mjnIFSjvHG3MYHW84GnksT/view?usp=sharing

Блок по 1600 байт всё равно написанная на коленке версия через TThread по принципу крякнул-бахнул опережает TParallel.For .  И только на блоках 6400 байт и более начинается выгода.  А не всегда удаётся распараллелить на такие большие блоки.

И вот , кстати я переписал , что файл читается в основном потококе и тогда заработало.

Цитата

procedure TThreadSignal.ReadBuf;
begin

if ThreadFile.BytesReady<=Counter then
    begin
      fCompleted  := True;
      if fi>0 then Suspend //Только старшему потоку разрешено читать   //Ждём пока буфер не будет прочитан.
      else ReadFileThread;

 

Подозреваю ,  что в андройде BlockRead можно только из основного потока вызывать. 

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...