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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.07.2013, 22:34   #11
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Constructor, inherit, property
Цитата:
которые я никогда не использовал в обычных однопоточных приложениях.
значит вы не писали свои классы(с наследованием)

да, тема не простая, но разобратся в ней вполне реально, просто нужно понимать механику.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 13.07.2013, 22:39   #12
-glykaman-
Пользователь
 
Аватар для -glykaman-
 
Регистрация: 13.07.2013
Сообщений: 18
По умолчанию

Цитата:
Сообщение от borderliner Посмотреть сообщение
Потоки в Дельфи кажутся слишком запутанной и муторной процедурой, поэтому не увидев это на конкретном примере трудно увидеть аналогию, тем более для тех кто никогда с ними не работал. Прикольно что текст описывающий потоки и обращения к ним занимает гораздо больше места чем сам конкретный алгоритм. Я прочитал много всяких ссылок и везде все по-разному. Constructor, inherit, property, execute и тонна всяких других вещей которые я никогда не использовал в обычных однопоточных приложениях.
Так по началу)) ТАкже с ООП по началу))) А еще путаются в голове потоки данных и потоки выполнения...

Возьми какой-нибудь конкретный пример повтори, если заработало - разбирай его подробно - до каждого ключевого слова.. Затем его уже подстраивай под свои нужды. Так я делаю если встречаюсь чем-то неизвестным. Долго но результативно + новые знания хорошо усваиваются.
Я тебе чем-то помог? Нажми слева на значок весов. Спасибо =)
Мой сайт с видеоуроками по программированию - http://programmerinfo.ru/
-glykaman- вне форума Ответить с цитированием
Старый 13.07.2013, 22:44   #13
borderliner
Новичок
Джуниор
 
Регистрация: 13.07.2013
Сообщений: 5
По умолчанию

Цитата:
Сообщение от -glykaman- Посмотреть сообщение
Сорри я не въехал походу...

Но объясните мне тогда
Вот три части которые дал ТС:
Код:
{1}
for i:=1 to m do
d[i]:=a[i]*sqr(b[i]);
 
{2}
for i:=m+1 to n do
d[i]:=a[i]+b[i];
 
{3}
for i:=n+1 to n+m do
d[i]:=a[i]-b[i];
Каждую из них отдельный независимый поток запихать и все, разве не это требуется?
поучится что все они выполняются параллельно, разве нет?
Да именно это я и имел ввиду создавая эту тему. 3 параллельных цикла и четвертый который дождется их завершения, чтобы получить элементы массива для последующей обработки.



Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
значит вы не писали свои классы(с наследованием)

да, тема не простая, но разобратся в ней вполне реально, просто нужно понимать механику.
Вы правы, поэтому я и спросил, потому что тема для меня новая и хотелось бы узнать у тех кто разбирается. Программирование сама по себе область очень и очень обширная все знать невозможно и часто сталкивание с новыми вещами неизбежно. Хотелось бы подробно разобраться в данном нетривиальном вопросе.
borderliner вне форума Ответить с цитированием
Старый 13.07.2013, 22:53   #14
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
ну а для отлавливания завершений работы потоков - можно вызывать исключение, но это долго, потому проще мне кажется добавить в потоки флаги говорящие о том закончена в них обработка или нет. и периодически просто опрашивать их по таймеру. можно еще через критическую секцию сделать или вообще тупо вызывать функцию специальную для конечных вычислений, на третий её вызов производить эти самые вычисления. в общем отловить результат не проблема если подумать.
у потоков есть свойство Terminated.
а исключение не долго вызвать, только это глупо, обрабатывать то кто будет? основной поток этого не сможет сделать.
Цитата:
Вы правы, поэтому я и спросил, потому что тема для меня новая и хотелось бы узнать у тех кто разбирается. Программирование сама по себе область очень и очень обширная все знать невозможно и часто сталкивание с новыми вещами неизбежно. Хотелось бы подробно разобраться в данном нетривиальном вопросе.
советую начать с ООП, так как дельфийские потоки восходят именно к нему(есть еще АПИшные потоки, там просто процедуру описываете и по ней создаете, но они не так удобны, и там тоже камни по синхронизации)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 13.07.2013, 23:00   #15
borderliner
Новичок
Джуниор
 
Регистрация: 13.07.2013
Сообщений: 5
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
советую начать с ООП, так как дельфийские потоки восходят именно к нему(есть еще АПИшные потоки, там просто процедуру описываете и по ней создаете, но они не так удобны, и там тоже камни по синхронизации)
Мне всегда легче понять из знакомого примера и начать с практики, а потом уже перейти к теории. Часто в приведенных примерах отсутствует наглядность, а это мне знакомый случай. Три потока независимо вычисляют необходимые части массива. Главная программа дожидается завершения всех трех потоков и только потом делает необходимые операции. Я просто не знаю как это все реализуется.
borderliner вне форума Ответить с цитированием
Старый 14.07.2013, 01:43   #16
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

Можно создать поток, который создаст ещё 3 потока. Один поток как TThread, остальные потоки можно покороче оформить через BeginThread (никто не запрещает использовать полностью TThread, но, ИМХО, это избыточно)
Код:
type
  MyThread = class(TThread)//этот поток активно контактирует с VCL, поэтому TThread
  private
    { Private declarations }
    c: single;
  protected
    constructor Create;
    procedure Execute; override;
    procedure WriteInForm; //для синхронизации при выводе в VCL
  end;
...
procedure f1;
begin
  {1}
  for i:=1 to m do
    d[i]:=a[i]*sqr(b[i]);
end;

procedure f2;
begin
  {2}
  for i:=m+1 to n do
    d[i]:=a[i]+b[i];
end;

procedure f3;
begin
  {3}
  for i:=n+1 to n+m do
    d[i]:=a[i]-b[i];
end;

constructor MyThread.Create;
begin
  inherited Create(false);
  FreeOnTerminate := true;
  //и прочая инициализация
end;

procedure MyThread.Execute;
var
  i: integer;
  id: array[1..3] of LongWord;
  thr: array[1..3] of Integer;
begin
  thr[1] := BeginThread(nil, 0, Addr(f1), nil, 0, id[1]);
  thr[2] := BeginThread(nil, 0, Addr(f2), nil, 0, id[2]);
  thr[3] := BeginThread(nil, 0, Addr(f3), nil, 0, id[3]);
  for i := 1 to 3 do WaitForMultipleObjects(Length(thr), @thr, True, INFINITE);
  for i := 1 to 3 do CloseHandle(thr[i]);

  {завершение}
  c:=0;
  for i:=1 to n+m do c:=c+d[i]*14523696*sin(i);
  Synchronize(WriteInForm)//Result:=c
end;

procedure MyThread.WriteInForm;
begin
  Form1.Edit1.Text := floattostr(c);//тут куда-нить вывод
end;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  thr := MyThread.Create
  ...
end;
Массивы в данном случае глобальные (камнями не кидать - это просто пример). Если не нравиться, то можно передавать указатель на них в параметре BeginThread'a
Это не лучший пример для изучения хотя бы лишь по тому, что смешаны 2 вида создания потоков (хотя они родственники)
eoln вне форума Ответить с цитированием
Старый 14.07.2013, 04:44   #17
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,442
По умолчанию

Цитата:
Каждую из них отдельный независимый поток запихать и все, разве не это требуется?
поучится что все они выполняются параллельно, разве нет?
Пример относительно простой вроде или я чего-то недогнал...
Тут несколько проблем:
1. Источник данных для вычисления всего 1, в него вносят и выносят. Параллельное выполнение уже невозможно без костылей.
2. Да, 3 потока стартуют одновременно, НО пока первый не закончит, 2 и 3 нечего делать, когда начнет работать 2, 3 будет стоять т.к. для него данные не готовы.
_
Итого, мы реализовали 3х поточный аналог функций, при этом потратив впустую время и ресурсы и не преуспели со скоростью вычислений.

Мне сложно разбить задачу ТС и привести пример потому я абстрагируюсь:
Представим что есть завод по сборке деталей. Состоит из 3 цехов: распаковка деталей со склада, сборка деталей в продукт, упаковка продукта.
Дали партию деталей 200 шт.

Вернемся к коду:
3 цеха это 3 цикла:
Код:
{1}
for i:=1 to m do
d[i]:=a[i]*sqr(b[i]);
 
{2}
for i:=m+1 to n do
d[i]:=a[i]+b[i];
 
{3}
for i:=n+1 to n+m do
d[i]:=a[i]-b[i];
Партия деталей, это:
Цитата:
d:array[1..n+m] of real;
И сейчас 2 и 3 цеха ждут пока первый отработает полностью, вместо того, чтобы работать сообща.

Чтобы работать сообща нужна всего 1 вещь: конвейерная лента.

С помощью неё возможно следующее:
Поставили деталь А на ленту
__
1 цех обработал А, передает А в цех 2, сообщает в цех 3, сколько осталось на складе, ждет сообщения от 2го, что тот получил без брака
__
Цех 2, получил деталь А, сообщает цеху 1, что тот может распаковать деталь Б но не отсылать
__
Цех 2 обработал деталь А, и послал её в цех 3, сообщил цеху 1 что готов к работе с Б, цех 1 передает Б
__
Цех 3 просто обрабатывает детали, будучи информированным от цеха 1, см узнает когда "это последняя деталь". Или же это можно делать в конце: Цех 1 сообщает в цех 2 и так до цеха 3.


Таким образом время на выполнения обработки сокращается в 3е, т.к. все 3е работают одновременно и сообща.

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

Последний раз редактировалось Человек_Борща; 14.07.2013 в 04:46.
Человек_Борща вне форума Ответить с цитированием
Старый 14.07.2013, 05:05   #18
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

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

я бы не пихал на практике каждую функцию отдельно, а просто создал один тип потока, и ему сообщал указатель на массив и его диапазон вычислений, и пусть со своим диапазоном че хочет, то и творит.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 14.07.2013 в 05:07.
Пепел Феникса вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с потоками -Jack- Общие вопросы Delphi 3 12.02.2013 23:21
Работа с потоками derElektroBesen Помощь студентам 3 17.07.2011 14:33
работа с потоками SHtirlic1 Общие вопросы Delphi 10 15.03.2011 20:03
Проблемы с потоками в С m9yt Общие вопросы C/C++ 4 14.04.2010 14:25
Работа с потоками Яр|/||< (^_^) Общие вопросы Delphi 5 09.03.2010 08:23