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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.08.2011, 18:40   #1
kardinal94
Форумчанин
 
Аватар для kardinal94
 
Регистрация: 26.04.2010
Сообщений: 105
По умолчанию Создание потоков

Возникла необходимость создания мультипоточного приложения. Необходима одновременная работа до 10 потоков.
В данный момент пытаюсь ее делать так:
Код:
for I := 0 to 9 do
  begin
potok:=demo.Create(false);
potok.Priority:=tpnormal;
potok.FreeOnTerminate:=true;
  end;
А сама процедура потока выглядит следующим образом:
Код:
procedure Demo.Execute;
var
  neiz, yours, itcount, i: integer;
  fbi: string;
  Inif: TInifile;
begin
  for yours := 0 to Form1.CheckListBox1.items.Count - 1 do
  Begin
    if Form1.CheckListBox1.checked[yours] = true then
    begin
      Inif := TInifile.Create(ExtractFilePath(ParamStr(0))
          + 'base\' + Form1.Memo2.Lines.Strings[yours]);
      fbi := Inif.ReadString('Readktor', 'Info', '');
      if lowercase(fbi) = 'phpbbadd' then
        phpbbgo(yours);
      if lowercase(fbi) = 'npadd' then
        npaddgo(yours);
    end;
  End;
То есть выполняются две процедуры phpbbgo(yours) & npaddgo(yours);
При этом стоит вопрос, а не должен ли я их синхронизировать? Как? Насколько я понимаю процедуры с входными нельзя синхронизировать с помощью функции Synchronize. И вообще правильно ли я делаю.
kardinal94 вне форума Ответить с цитированием
Старый 13.08.2011, 18:50   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Начнём с того, что с VCL компонентами нельзя работать не из главного потока. Все эти обращения к Form1.CheckListBox1 и Form1.Memo2 рано или поздно завалят ваше приложение.

> potok.FreeOnTerminate:=true;

есть шанс, что эта строчка выполнится уже после того, как поток отработает и завершится.

> а не должен ли я их синхронизировать?

зависит от того, что в них происходит.

> входными нельзя синхронизировать с помощью функции Synchronize

во-первых, Synchronize() ничего не "синхонизирует". Этот метод только обеспечивает выполнение переданной ему процедуры в главном потоке.

во-вторых, параметры передавать можно, но не явно, а через поля класса, например.

> И вообще правильно ли я делаю

не заметно. 10 потоков будут насиловать одни и те же ini файлы. Смысл ваших действий?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 13.08.2011, 19:39   #3
kardinal94
Форумчанин
 
Аватар для kardinal94
 
Регистрация: 26.04.2010
Сообщений: 105
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
Начнём с того, что с VCL компонентами нельзя работать не из главного потока. Все эти обращения к Form1.CheckListBox1 и Form1.Memo2 рано или поздно завалят ваше приложение.
И как к ним тогда обращаться? О_о

Цитата:
Сообщение от veniside Посмотреть сообщение
> а не должен ли я их синхронизировать?

зависит от того, что в них происходит.
В них происходит отправка POST/GET запросов, парсинг.

Цитата:
Сообщение от veniside Посмотреть сообщение
> входными нельзя синхронизировать с помощью функции Synchronize

во-первых, Synchronize() ничего не "синхонизирует". Этот метод только обеспечивает выполнение переданной ему процедуры в главном потоке.

во-вторых, параметры передавать можно, но не явно, а через поля класса, например.
А как насчет конкретного примера?

Цитата:
Сообщение от veniside Посмотреть сообщение
> И вообще правильно ли я делаю

не заметно. 10 потоков будут насиловать одни и те же ini файлы. Смысл ваших действий?
Действительно только сейчас заметил, мне надо чтобы каждый новый потом брал следующий файл, только пока ума не приложу как это реализовать.
kardinal94 вне форума Ответить с цитированием
Старый 13.08.2011, 19:59   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> И как к ним тогда обращаться?

из потока лучше никак. Не, ну в самом деле, что там такого супер важного в этом мемо, чего нельзя передать в поток заранее?

Если уж очень надо обратиться, то используйте Synchronize(), PostMessage() или любой другой доступный механизм межпотокового взаимодействия.

> В них происходит отправка POST/GET запросов, парсинг.

ну, это ни о чём не говорит. Скажем так, если в них идёт обращение к совместно разделяемым ресурсам (например, один парсер на всех, или один TStrignList, куда сбрасываются результаты парсинга), то оборачивайте доступ к ним критическими секциями, это и будет синхронизация, а не вызов Syncronize()!

> А как насчет конкретного примера?

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

> ума не приложу как это реализовать

Ну это как раз просто:

Код:
Demo = class(TThread)
private
  f_ini: string;

  .....

public
  constructor Create(const ini: string);
end;

{ Demo }

constructor Demo.Create(const ini: string);
begin
  f_ini := ini;
  FreeOnTerminate := True;
  Priority := tpnormal;
  //
  inherited Create(False);
end;
Одним выстрелом 3-х зайцев:

1) внутри потока не нужно больше обращаться к VCL, т.к. имя файла уже передано
2) FreeOnTerminate := True; выполняется в нужном месте
3) Проще выглядит создание потоков:

Код:
for I := 0 to 9 do
  demo.Create(ExtractFilePath(ParamStr(0))  + 'base\' + Form1.Memo2.Lines.Strings[l]); // как пример
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 15.08.2011, 12:04   #5
jskorvin
Пользователь
 
Регистрация: 27.09.2010
Сообщений: 16
По умолчанию

Читайте настройки ини в главном потоке и передавайте их параметром (как было замечено выше).

Моя реализация подобного
Код:
TH.host:=SES[StrToInt(SEnum)][0];
TH.query:=SES[StrToInt(SEnum)][1];
TH.LinksMask:=SES[StrToInt(SEnum)][2];
TH.totalpages:=SES[StrToInt(SEnum)][3];
TH.sename:=SES[StrToInt(SEnum)][4];
TH.NextPageShab:=SES[StrToInt(SEnum)][5];
SES двумерный массив с параметрами. При старте сначала полностью читается ини, а затем уже передаются параметры потокам.

Ну это так, отвлечение, заострить внимание я хотел не на этом.
Проверьте как стартуют потоки, недавно в похожем случае выяснилось, что они стартанут разом после выполнения цикла. Вероятно у вас будет также. На 10 потоках вы этого не заметите, а вот 100 уложит вам машину.
jskorvin вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание потоков cargo29 Общие вопросы Delphi 16 07.08.2011 12:11
Создание большого количества потоков Crystallon Общие вопросы Delphi 3 03.06.2011 02:42
Синхронизация потоков в С++ erazer89 Помощь студентам 0 27.04.2010 20:14
создание потоков MaRKer.nsk Общие вопросы C/C++ 6 28.03.2010 20:59
Перенаправление потоков Carbon Win Api 5 25.11.2007 14:46