Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.02.2014, 23:59   #1
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию Работа с потоками.

Есть мемо, в котором 23 строки с инфой и есть 3 потока.

Как мне отправить каждому потоку равное количество строк на обработку?

В голову приходила идея, что то вроде:

Код:
str:=Math.Ceil(Memo2.Lines.Count / High(ThreadArray)); // делим количество строк в мемо на количество потоков
    memo:=Memo2.Lines;

    for i:=Low(ThreadArray) to High(ThreadArray) do
    begin

      for k := 0 to str do
      begin
        if Trim(memo.Strings[k])<>'' then
        begin
          memotext.Strings[k]:=memo.Strings[k];
          memo.Delete(k);
        end;
      end;

      ThreadArray[i]:=Thr.Create(memotext);
      ThreadArray[i].FreeOnTerminate:=true;
      ThreadArray[i].Resume;
      ThreadArray[i].Priority:=tpNormal;

      memotext.Free;
    end;
Но похоже это все на "Х", причем с ошибкой.

Поможете?
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 00:37   #2
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Выдели массив стринг под размер массива потоков.

var StringList: Array of string;
begin
SetLength(StringList, Length(ThreadArray));

В цикле от первой строки до последней
For i := 0 to Memo1.Count - 1

запиши каждую строку в элемент массива по индексу. По достижении максимального индекса массива, сдвигай индекс массива на ноль.

inc(k);
if k > Length(StringList) then k := 0
StringList[k] := StringList[k] + Memo1Lines[i] + #13#10;

В итоге получишь в массиве все свои строки. Отправляй каждый стринг массива в поток.

ThreadArray[i]:=Thr.Create(StringList[i]);

Последний раз редактировалось doktor255; 22.02.2014 в 00:51.
doktor255 вне форума Ответить с цитированием
Старый 22.02.2014, 01:51   #3
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,869
По умолчанию

Цитата:
Сообщение от bilibian Посмотреть сообщение
Но похоже это все на "Х", причем с ошибкой.
Естественно с ошибкой. Кто же удаляет элементы массива/списка и т.п. в прямом цикле for.

Цитата:
Сообщение от doktor255 Посмотреть сообщение
Выдели массив стринг под размер массива потоков.

var StringList: Array of string;
begin
SetLength(StringList, Length(ThreadArray));

В цикле от первой строки до последней
For i := 0 to Memo1.Count - 1

запиши каждую строку в элемент массива по индексу. По достижении максимального индекса массива, сдвигай индекс массива на ноль.

inc(k);
if k > Length(StringList) then k := 0
StringList[k] := StringList[k] + Memo1Lines[i] + #13#10;

В итоге получишь в массиве все свои строки. Отправляй каждый стринг массива в поток.

ThreadArray[i]:=Thr.Create(StringList[i]);
Иногда лучше жевать, чем говорить.
Читать внимательно вопрос нужно даже если вопрос глупый.

Последний раз редактировалось Stilet; 22.02.2014 в 10:28.
northener вне форума Ответить с цитированием
Старый 22.02.2014, 09:24   #4
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

пишу так:

Код:
procedure TForm1.Button2Click(Sender: TObject);
  var i,k,str:Integer;
      memotext:TStringList;
begin
    memotext:=TStringList.Create;
    str:=Math.Ceil(Memo2.Lines.Count / High(ThreadArray)); // количество записей делим на количество потоков
    k:=0;

    for i:=Low(ThreadArray) to High(ThreadArray) do
    begin

      while True do
      begin
        if Trim(Memo2.Lines[k])<>'' then
        begin
          memotext.Add(Memo2.Lines[k]);
        end;
        Inc(k);
        if (memotext.Count>=str) or (k>Memo2.Lines.Count-1) then Break;
      end;
       
      // До этого момента все работает.

      ThreadArray[i]:=Thr.Create(memotext.text); // Ошибка в передаваемом параметре, который в конструкторе объявлен как TStrings
      ThreadArray[i].FreeOnTerminate:=true;
      ThreadArray[i].Resume;
      ThreadArray[i].Priority:=tpNormal;

      memotext.Clear;
    end;
    memotext.Free;
end;
В переменной memotext находятся строки которые необходимо передать в поток. Проблема заключается в том, что при компиляции появляется ошибка и курсор указывает на строку memotext.text

А если записать так:
Код:
ThreadArray[i]:=Thr.Create(memotext);
То появляется ошибка: Access violation at address 00000000. Read of address 00000000

В чем может быть дело?

Последний раз редактировалось bilibian; 22.02.2014 в 09:40.
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 10:26   #5
wendstor
Пользователь
 
Аватар для wendstor
 
Регистрация: 28.12.2011
Сообщений: 20
По умолчанию


Вариантов много, а то что вы пишите, так это от незнания.
Вам проще отслеживать, завершения работы потока, и добавлять данные (из списка) либо уничтожать поток. Вот варианты реализации:
1. CallBack процедуры внутри класса потока, которая бы возращала какие либо данные о том что проделал поток. Пример callback функции
Код:
TMyProc = procedure (blabla1: string) of object;
{.............}
В гугле полно, материала. Читаем и учимся

2. Создать внутреннюю procedure/function в классе потока, с возращением каких либо данных. Вот ссылка

И вообще читайте всю инфу по потокам...

Последний раз редактировалось wendstor; 22.02.2014 в 10:28.
wendstor вне форума Ответить с цитированием
Старый 22.02.2014, 10:35   #6
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

wendstor, если использовать тот же код, что я приложил выше и вместо переменной memotext отправлять в поток полный список из мемо (ThreadArray[i]:=Thr.Create(memo2.lines);), то все работает, только каждый поток проделывает одно и тоже.

По этому я решил разделить список мемо на равные части и распределить по потокам.
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 10:41   #7
wendstor
Пользователь
 
Аватар для wendstor
 
Регистрация: 28.12.2011
Сообщений: 20
По умолчанию

Цитата:
Сообщение от bilibian Посмотреть сообщение
wendstor, если использовать тот же код, что я приложил выше и вместо переменной memotext отправлять в поток полный список из мемо (ThreadArray[i]:=Thr.Create(memo2.lines);), то все работает, только каждый поток проделывает одно и тоже.

По этому я решил разделить список мемо на равные части и распределить по потокам.
Да зачем делить ??? Просто брать из списка строку отправлять потоку, после обработки потоком данных, удалять из списка, далее заново передаём потоку данные из списка, и т.д. как только список будет равняется 0, то следующие отработанные(завершенные) потоки удалять...
Читайте всё по потокам ссылку дал как пример в п. 2.
wendstor вне форума Ответить с цитированием
Старый 22.02.2014, 11:27   #8
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

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

Если можно, то покажите, пожалуйста, пример, который более наглядно все объясняет.
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 12:12   #9
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Цитата:
Сообщение от northener Посмотреть сообщение
Иногда лучше жевать, чем говорить.
Читать внимательно вопрос нужно даже если вопрос глупый.
Вопрос был, как отправить в каждый поток одинаковое количество строк. Я показал как равномерно распределить эти строки по потокам. ЧТО НЕ ТАК?

Цитата:
Сообщение от bilibian Посмотреть сообщение
По этому я решил разделить список мемо на равные части и распределить по потокам.
Я выше привёл код, как разбросать строки из мемо по массиву стринг, равному по длине массиву потоков, а после отправить в каждый поток свой string содержащий строки. Что не устраивает?

Последний раз редактировалось doktor255; 22.02.2014 в 12:14.
doktor255 вне форума Ответить с цитированием
Старый 22.02.2014, 12:52   #10
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

doktor255, я пробовал Ваш способ, но в дальнейшем не получается обратиться к конкретной строке уже в самом потоке. Тут уже не применить index, lines и тому подобные команды.
bilibian вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с потоками ThreadDelphi Общие вопросы Delphi 3 08.04.2012 18:58
Работа с потоками derElektroBesen Помощь студентам 3 17.07.2011 14:33
Работа с потоками gagarin0 Win Api 4 05.11.2010 02:30
Работа с потоками Нюська Общие вопросы Delphi 3 27.05.2009 00:52
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25