Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64

Создание потоков для обработки файлов

04.08.2017, 11:06. Показов 4762. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите создать поток
С потоками раньше дел не имел. Есть код на кнопке, обрабатывает файлы последовательно. Это долго. Хочется разбить на потоки

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TForm1.Button1Click(Sender: TObject);
begin
//список файлов находится в стринглисте StrList
//есть прогрессбар который увеличивается по мере обработки файлов
  ProgressBar1.Min := 0;
  ProgressBar1.Max := StrList.Count - 1;
  for I := 0 to StrList.Count - 1 do
  begin
    ProgressBar1.Position := I;
    Application.ProcessMessages;
//пошла обработка файла
    JPG.LoadFromFile(StrList[I]);
//что-то сделали, сохраняем
      JPG.SaveToFile(GetCurrentDir + '\' + ExtractFileName(StrList[I]+ ' (1).jpeg');
    end;
  end;
Как этот цикл разбить на потоки, чтобы каждый файл обрабатывался в своем потоке и все потоки после обработки файла увеличивали на +1 прогрессбар?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.08.2017, 11:06
Ответы с готовыми решениями:

Загрузить несколько файлов для обработки
Подскажите пожалуйста как загрузить несколько файлов посредством OpenDialog и обработать их все.

Создание приложений для обработки массивов
В некотором цехе имеется определенное количество станков, требующих наладки. Известно время наладки каждого станка.Определить номера тех...

Создание приложений для обработки массивов
Известны итоги забега спортсменов на 100 метров. Требуется составить команду из четырех лучших спортсменов для участия в эстафете 4x100;

36
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
04.08.2017, 16:14  [ТС]
Студворк — интернет-сервис помощи студентам
PuntoSwitcher помогает забыть о переключении
0
04.08.2017, 16:28

Не по теме:

а когда ты в русской раскладке начинаешь писать TMyThr, тоже переключает? просто интересно, ведь насколько я знаю, пунто ориентируется по базе слов

0
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
04.08.2017, 16:45  [ТС]
TMyThr не использую, а так проблем нет все переключает.

по потоку. если вставить задержку в 500 мс на каждые 4 потока то битых файлов нет. но по моему играться с задержками времени неправильно. должен же быть способ заставить потоки не портить файлы и ждать ресурсы.
0
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
04.08.2017, 16:50  [ТС]
при задержке в потоках в 300 мс вываливается такая ошибка
Миниатюры
Создание потоков для обработки файлов  
0
04.08.2017, 16:57

Не по теме:

ты не понял. пунто как работает? на лету переключает, верно? так вот, желая набрать TMyThread, ты пишешь ЕЬнЕркуфв. пунто переключит или нет?

0
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
04.08.2017, 17:03  [ТС]
да нормально переключает уже с 3 буквы еьн сразу переходят в tmy
0
04.08.2017, 17:27

Не по теме:

б-р-р, IMHO такая дрянь этот PuntoSwitcher :-!

0
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
04.08.2017, 17:32  [ТС]
ну что вы перешли PuntoSwitcher, скажите лучше что с потоками делать. когда запускаю по 4 потока каждые 500 мс все норм. 8 потоков через 500 мс вылетает ошибка нет ресурсов и в новых картинках белый лист. это что косяки TJPEGImage, что не может нормально создавать много своих экземпляров в памяти?
0
 Аватар для Пытливый
3764 / 2272 / 705
Регистрация: 29.05.2013
Сообщений: 9,622
04.08.2017, 18:26
Запустив такой код в каталоге с 1000 файлов вы создаете 1000 потоков, будет файлов 10000 будет 10000 потоков... если будет. Работа с файлами всегда упирается в производительность дисковой подсистемы и если у вас не SSD, то представляете что происходит с диском, когда ему 1000 потоков посылают команду прочитать свою порцию данных? Весь ваш выигрыш от использования потоков будет съеден. Поэтому всему должна быть мера и свой подход.
Делается обычно следующее. Создается фиксированная очередь из потоков, думаю 10 более чем достаточно для вашей задачи и в каждый из потоков передают свою порцию файлов, например 50 файлов. Завершаясь поток удаляется из очереди и в освободившееся место создается новый поток со следующей порцией файлов. Все это повторяется пока все файлы для обработки не закончатся.
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
04.08.2017, 21:06
быстрое исследование показало, что использование jpg.compress в потоке не канает
всем спасибо, все свободны )))
наверное есть причины что это не потокобезопасный метод

для желающих поиграться вот. даже SaveToFile в Execute есть закомментированное
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
unit Unit1;
 
interface
 
uses
  classes, types, forms, ExtCtrls, Controls, StdCtrls, SysUtils, Dialogs,
  System.Generics.Collections, vcl.imaging.jpeg;
 
type
  TMyThread=class(TThread)
    fname:string;
    jpg:TJPegImage;
    constructor Create(AFname:String; TermProc:TNotifyEvent);
    procedure Execute; override;
    destructor Destroy; override;
  end;
 
 
  TForm1 = class(TForm)
    bStart: TButton;
    m1: TMemo;
    procedure bStartClick(Sender: TObject);
  private
    ready:integer;
    procedure ThreadTerminated(Sender: TObject);
    procedure RunThread;
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses
  vcl.graphics ;
const
  max_th=100;
 
 
{$R *.dfm}
 
 
{ TForm1 }
 
 
procedure TForm1.RunThread;
var
  th:TMyThread;
  path,fn:string;
begin
  path:=extractFilePath(ParamStr(0));
  fn:=format('%.02d.jpg',[ready]);
  th:=TMyThread.Create(path+fn,ThreadTerminated);
  m1.lines.add('begin -- '+fn);
  th.Start;
  Inc(ready);
end;
 
procedure TForm1.bStartClick(Sender: TObject);
begin
  ready := 0;
  while ready<5 do
    runThread;
end;
 
 
procedure TForm1.ThreadTerminated(Sender:TObject);
var
  th:TMyThread absolute Sender;
begin
  th.jpg.SaveToFile(th.fname);
  m1.lines.add('end -- '+extractfilename(th.fname));
  if ready<max_th then
    RunThread;
end;
 
 
{ TMyThread }
constructor TMyThread.Create(AFname: String; TermProc: TNotifyEvent);
begin
  inherited Create(true);
  FreeOnTerminate := true;
  fname := AFname;
  OnTerminate := TermProc;
  jpg:=TJPEGImage.Create;
end;
 
destructor TMyThread.Destroy;
begin
  jpg.free;
  inherited;
end;
 
procedure TMyThread.Execute;
var b:TBitmap;
  i: Integer;
const
  SZ:TSize=(cx:300;cy:150);
begin
  b:=Tbitmap.Create;
  b.SetSize(sz.cx,sz.cy);
  for i := 0 to 9 do
    b.Canvas.Rectangle(random(sz.cx),random(sz.cy),random(sz.cx),random(sz.cy));
  jpg.CompressionQuality := 70;
  jpg.Assign(b);
  if FileExists(fname) then
    deletefile(fname);
  // jpg.SaveToFile(th.fname);
  b.Free;
end;
 
end.
0
3 / 3 / 0
Регистрация: 19.04.2013
Сообщений: 64
07.08.2017, 09:41  [ТС]
всем спасибо. потоки работают, графика нет. по графике создам свою тему.

Добавлено через 15 минут
Чем заменить TJPEGImage для многопоточной обработки?
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.08.2017, 10:18
эээ
я вспомнил кой что
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
procedure TMyThread.Execute;
var
  i: Integer;
  b:TBitmap;
begin
  b:=TBitmap.Create;
  b.SetSize(300,150);
  b.Canvas.Lock;
  try
    for i := 0 to 5 do
      b.Canvas.Rectangle(Random(300),Random(150),Random(300),Random(150));
    jpeg.Assign(b);
    jpeg.Canvas.Lock;
    try
      if FileExists(FName) then
        DeleteFile(fname);
      jpeg.SaveToFile(fname);
    finally
      jpeg.canvas.Unlock;
    end;
  finally
    b.Canvas.Unlock;
    b.Free;
  end;
end;
1
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
07.08.2017, 10:22
krapotkin, при jpeg.Canvas.Lock; будет работать в потоке?
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.08.2017, 10:48
код рабочий
0
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
07.08.2017, 12:15
krapotkin, у меня
Delphi
1
jpg: TJPEGImage;
пишет, что нет объекта Canvas!
Delphi XE2
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,684
Записей в блоге: 21
07.08.2017, 12:28
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
unit Unit1;
 
interface
 
uses
  classes, types, forms, ExtCtrls, Controls, StdCtrls, SysUtils, Dialogs,
  System.Generics.Collections, vcl.imaging.jpeg;
 
type
  TMyThread=class(TThread)
    FName:String;
    Result:integer;
    jpeg:TJPEGImage;
    constructor Create(AFname:string; TermProc:TNotifyEvent);
    procedure Execute; override;
    destructor Destroy; override;
  end;
 
 
  TForm1 = class(TForm)
    bStart: TButton;
    m1: TMemo;
    procedure bStartClick(Sender: TObject);
  private
    T1:int64;
    Started:integer;
    Finished:integer;
    Sum:integer;
    procedure ThreadTerminated(Sender: TObject);
    procedure RunThread;
  end;
 
var
  Form1: TForm1;
 
implementation
 
uses
  graphics;
 
const
  max_th=100;
  max_same_time=10;
 
 
{$R *.dfm}
 
 
{ TForm1 }
 
 
procedure TForm1.RunThread;
var
  th:TMyThread;
begin
  th:=TMyThread.Create(ExtractFilePath(ParamStr(0))+Format('%.03d.jpg',[started]),ThreadTerminated);
//  m1.lines.add('begin -- '+inttostr(Started));
  th.Start;
  Inc(Started);
end;
 
procedure TForm1.bStartClick(Sender: TObject);
begin
  bStart.Enabled := false;
  m1.lines.clear;
  t1:=TThread.GetTickCount;
  Started := 0;
  Finished := 0;
  Sum := 0;
  while Started < max_same_time do
    runThread;
end;
 
 
procedure TForm1.ThreadTerminated(Sender:TObject);
var
  th:TMyThread absolute Sender;
begin
  Inc(Finished);
//  m1.lines.add('end -- '+inttostr(th.Result));
  Sum:=Sum+th.Result;
 
  if Started<max_th then
    RunThread;
 
  if Finished=max_th then
  begin
    m1.lines.add('========================');
    m1.lines.add('Итог: '+inttostr(sum));
    m1.Lines.Add(IntToStr(max_th)+' threads');
    m1.Lines.Add(IntToStr(TThread.GetTickCount-t1)+' msec');
    bStart.Enabled:=true;
  end;
end;
 
 
{ TMyThread }
constructor TMyThread.Create(AFname:string; TermProc: TNotifyEvent);
begin
  inherited Create(true);
  FreeOnTerminate := true;
  FName := AFname;
  OnTerminate := TermProc;
  jpeg:=TJPEGImage.Create;
end;
 
 
destructor TMyThread.Destroy;
begin
  jpeg.Free;
  inherited;
end;
 
procedure TMyThread.Execute;
var
  i: Integer;
  b:TBitmap;
begin
  b:=TBitmap.Create;
  b.SetSize(300,150);
  b.Canvas.Lock;
  try
    for i := 0 to 5 do
      b.Canvas.Rectangle(Random(300),Random(150),Random(300),Random(150));
    jpeg.Assign(b);
    jpeg.Canvas.Lock;
    try
      if FileExists(FName) then
        DeleteFile(fname);
      jpeg.SaveToFile(fname);
    finally
      jpeg.canvas.Unlock;
    end;
  finally
    b.Canvas.Unlock;
    b.Free;
  end;
end;
 
end.


Добавлено через 16 секунд
Berlin
0
Житель Земли
 Аватар для DenNik
3004 / 3026 / 390
Регистрация: 26.07.2011
Сообщений: 11,465
Записей в блоге: 1
07.08.2017, 12:38
в общем, с моим старым TJPEGImage работает так. проверил на 39 BMP-файлах общим объемом более 200мб. все файлы сконвертировались
Кликните здесь для просмотра всего текста
Delphi
1
2
3
4
5
6
TTThread = class(TThread)
    FileName: string;
    Success: boolean;
  protected
    procedure Execute; override;
  end;
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
procedure TTThread.Execute;
var
  bmp: TBitmap;
  jpg: TJPEGImage;
  fJpegName: string;
begin
  // конвертирование BMP в JPG
  fJpegName:= DirOut + ChangeFileExt(ExtractFileName(FileName),'.jpg');
  bmp:= TBitmap.Create;
  jpg:= TJPEGImage.Create;
  bmp.LoadFromFile(FileName);
  bmp.Canvas.Lock;
  try
    jpg.Assign(bmp);
    jpg.CompressionQuality:= 100;
    jpg.Compress;
    if FileExists(fJpegName) then DeleteFile(fJpegName);
    jpg.SaveToFile(fJpegName);
  finally
    jpg.Free;
    bmp.Canvas.Unlock;
    bmp.Free;
  end;
  Success:= FileExists(fJpegName);
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.08.2017, 12:38

Создание приложений для обработки массивов
12. Автомобиль некоторой модели собирают из n1 деталей пер¬вого типа, n2 деталей второго типа и т.д., nk деталей k-го типа. На складе...

Динамическое создание компонентов MEMO для потоков и последующее обращение к ним
Всю ночь бьюсь Подскажите, как создать N вкладок в них X вкладок И в вот эти X вкладки запихнуть компоненты TMemo? При этом так,...

Не получается сделать программный комплекс для обработки файлов xml
Здравствуйте, нужна помощь! Не получается сделать программный комплекс для обработки файлов .xml файлов ЭСВЧ (электронный счётов-фактур). ...

Разработать программу совместной обработки файлов F1 и F2 для формирования выходного документа типа F3
Помогите с программой. За ранее огромное спасибо. Задание нужно опубликовать в текстовом виде прямо в сообщении. Согласно Правилам...

Составить программу создания и обработки 3-х файлов данных, содержащего сведения для сотрудников ГИБДД
База данных «Автомобили» Составить программу создания и обработки 3-х файлов данных, содержащего сведения для сотрудников ГИБДД. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru