Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2012.03.11;
Скачать: CL | DM;

Вниз

Потоки   Найти похожие ветки 

 
YURY   (2011-11-29 12:58) [40]

sniknik, практика показывает обратное.


 
Сергей М. ©   (2011-11-29 12:58) [41]


> сервер у нас оракловый


А что, Оракл разве не позволяет запуск запросов на выполнение в неблок.режиме ?
Я просто не в курсе ..


> Очерёдность у них определена во входных параметрах


Да нашиша передавать параметром "очередность"-то ?
Зачем заставлять рабочие потоки выполнять несвойственную им задачу диспетчеризации ?


 
Медвежонок Пятачок ©   (2011-11-29 13:00) [42]

практика показывает обратное.

Ну и в чем тогда проблема?
Если практика показывает, значит процедуры ты уже запускал из под потоков.
Так?
Так.
Тогда в чем же проблема?


 
sniknik ©   (2011-11-29 13:01) [43]

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


 
sniknik ©   (2011-11-29 13:03) [44]

> значит процедуры ты уже запускал из под потоков.
скорее из под процессов, но не говорит... а там параллельность от ядер "включается".


 
Anatoly Podgoretsky ©   (2011-11-29 13:03) [45]

> YURY  (29.11.2011 12:55:38)  [38]

Вот ты запустил два потока и ничего тебе не помешало.


 
Сергей М. ©   (2011-11-29 13:04) [46]


> Медвежонок Пятачок ©   (29.11.11 13:00) [42]


Не запускал он их)
Похоже он запустил несколько экземпляров клиентских процессов (на одном хосте или на разных - не суть как важно), дал каждому из них команду выпониль такую-то свою ХП и замерил время, за которое все эти процессы получат результаты своих запросов.


 
YURY   (2011-11-29 13:04) [47]

Медвежонок Пятачок, действительно запустил. Параллельно. И они отлично работают. Гораздо быстрее, чем последовательно. Но в том и суть, что не все они должны запускаться параллельно, а чать из них - строго после окончания других. Это как идти в магазин, говоря по телефону и кушая мороженое - три дпроцедуры. Но совершить покупку (четвёртая процедура) можно лишь по окончании процедуры прихода в магазин.


 
Anatoly Podgoretsky ©   (2011-11-29 13:05) [48]

> YURY  (29.11.2011 12:58:40)  [40]

Моя практика и мониториг тоже показывает обратно, видно как потоки за
процессор дерутся и это не бесплатно.


 
YURY   (2011-11-29 13:05) [49]

Сергей М., совершенно верно.


 
Anatoly Podgoretsky ©   (2011-11-29 13:09) [50]

> sniknik  (29.11.2011 13:01:43)  [43]

Сервер или запросы не в порядке


 
YURY   (2011-11-29 13:10) [51]

Anatoly Podgoretsky, Потоки запускаются на клиенте. Каждый поток инициирует выполнение хранимой процедуры на сервере. Процессор на клиенте вообще не причём. На сервере у нас 40 процессоров. Если я с клиента инициирую выполнение всех хранимых процедур на сервере последовательно, то общее время выполнения в несколько раз больше, чем при параллельном инициировании выполнения с помощью потоков.


 
Медвежонок Пятачок ©   (2011-11-29 13:11) [52]

Ну если запускал, то включаем голову и думаем:

Что мы имеем?
Что надо сделать?

Имеем 20 хранимок.
1. Из них 10 можно запускать независимо от всего.
2. 3 процедуры нужно выполнить последовательно, причем первая из них - стартует независимо от всех других
3. Остальные тоже друг за другом, первая тоже независимо от всех.

Итого:

Нужно 10 + 2 потоков, в которые передаются списки процедур.
В первых десяти список будет из одного элемента.
В двух последних списки будут из трех и семи элементов.

запускаем потоки, потоки перебирают списки и запускают хранимки.

Все!


 
Сергей М. ©   (2011-11-29 13:11) [53]


> Anatoly Podgoretsky ©   (29.11.11 13:05) [48]


Ну тут некий выигрыш в произ-ти параллельно выполняемых сервером запросов возможно произрастает из врЕменного кеширования сервером многократно используемых клиентскими запросами наборов данных.


 
Anatoly Podgoretsky ©   (2011-11-29 13:12) [54]

> YURY  (29.11.2011 13:10:51)  [51]

Вместо того чтобы поискать где бутылочное горло, решил сделать велосипед с
трехугольными колесами


 
Anatoly Podgoretsky ©   (2011-11-29 13:17) [55]

> Сергей М.  (29.11.2011 13:11:53)  [53]

Судя по его описанию, у него чего то не в порядке.
А кеширование происходит и используется независимо от потоков.
Конечно я делаю все чтобы это произошло.


 
YURY   (2011-11-29 13:18) [56]

Медвежонок Пятачок, проблема в том, что заранее я не знаю сколько хранимок, какие из них и в какой последовательности выберет пользователь для выполнения своих потребностей. Это происходит на этапе выполнения. Поэтому я не могу заранее создать несколько разных классов потоков - каждый для своей хранимки. Потому и создаю один класс.


 
Медвежонок Пятачок ©   (2011-11-29 13:20) [57]

да все намного банальнее.
вместо того, чтобы подумать над тем, что же я должен напрограммировать,

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


он начинает сразу проектировать некие абстрактные потоки, которые никак не отвечают поставленной задаче.
Оказывается эти потоки нужно диспетчеризировать.
А диспетчера нет.
Поэтому костыль в виде вайтфор и прочего.

В то время как решение [52] - на поверхности лежит и руками машет.


 
Медвежонок Пятачок ©   (2011-11-29 13:21) [58]

Медвежонок Пятачок, проблема в том, что заранее я не знаю сколько хранимок,

1. Заранее знать не надо.
Надо обработать выбор юзера, что он там себе навыбирал.
Затем осмыслить его и формализовать.


 
Медвежонок Пятачок ©   (2011-11-29 13:24) [59]

Бил гейтц, когда писал свой инет проводник, тоже не знал, пойдешь ли ты на мастера делфи его программой.
Однако же написал его и он даже ходит на мастера делфи.


 
YURY   (2011-11-29 13:24) [60]

Anatoly Podgoretsky, тощущение, что мы друг друга не понимаем ) Давайте так. Хранимка А выполняется за 15 минут. Хранимка Б за 40. При последовательном запуске обоих хранимок общее время выполнения 55 минут. При параллельном (используя потоки) - 40 минут 5 секунд. Имеем выигрыш во времени 14 минут 55 секунд. Это реальные данные. Вообще же хранимок несколько десятков и их количество увеличивается со временем.


 
Медвежонок Пятачок ©   (2011-11-29 13:33) [61]

Поэтому я не могу заранее создать несколько разных классов потоков - каждый для своей хранимки.

Нужен ОДИН класс потока.

Который умеет запускать одну хранимку, или список хранимок последовательно.

PS Чернилами для седьмого класса можно писать и в первом и в седьмом и в десятом классах.
И даже на пенсии можно писать чернилами для седьмого класса.


 
sniknik ©   (2011-11-29 13:34) [62]

> При параллельном (используя потоки) - 40 минут 5 секунд.
т.е. вопрос решен? потоки работают.

или
> Имеем выигрыш во времени 14 минут 55 секунд.
делим шкуру не убитого медведя?

вообще ИМХО, вот это
> что не все они должны запускаться параллельно, а чать из них - строго после окончания других.
наводит на мысль что потоки вообще не нужны...
нужен ассинхронный режим, с, у некоторых, в "онкомплит" запуском еще одного выполнения.


 
YURY   (2011-11-29 13:37) [63]

Медвежонок Пятачок, в реальности поток один и он простейший.

type
 TMyThread = class(TThread)
 private
   { Private declarations }
 public
   _ADOQuery     : TADOQuery;
   _Connection   : TADOConnection;
   _ProcedureName: String;
   _Tag          : Longint;
   Msg           : String;
   ReturnValue   : Integer;
 protected
   procedure Execute; override;
 end;

implementation

procedure TMyThread.Execute;
var
 i: Integer;
begin
 with TADOStoredProc.Create(nil) do
 try
   CommandTimeout := 0;
   CursorLocation := clUseServer;
   Connection     := _Connection;
   ProcedureName  := _ProcedureName;
   Parameters.Refresh;
   Parameters.ParamValues["@Msg"] := "";

   for i := 0 to Parameters.Count - 1 do
     if (Parameters.Items[i].Direction = pdInput) and
        (_ADOQuery.Locate("f_ProcName;f_ParamName",
               VarArrayOf([ProcedureName, Parameters.Items[i].Name]), [])) and
        (not _ADOQuery.FieldByName("f_Value").IsNull) then
       Parameters.Items[i].Value := _ADOQuery.FieldValues["f_Value"];

   ExecProc;

   Msg := Parameters.ParamValues["@Msg"];
   ReturnValue := Parameters.ParamValues["@Return_Value"];
 finally
   Free;
 end;
end;

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


 
Медвежонок Пятачок ©   (2011-11-29 13:39) [64]

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

Не, это клиника.
Лучше научи своего кота программировать.
У него быстрее получится.


 
sniknik ©   (2011-11-29 13:41) [65]

> ошибка та же, что и в первоначально приведённом примере с VCL...
ну так и читай ветку сначала...
> а не обращайся к объектам VCL формы без синхронизации. или думаешь обманул систему своими указателями...?
и т.д. ничего же не изменилось.


 
Сергей М. ©   (2011-11-29 13:44) [66]


> Осталось только научить его ожидать завершения другого потока


Ты чего какой настырный ?)

Зачем ты упорно пытаешься заставить рабочий поток класса TMyThread выполнять совершенно несвойственную ему работу ? Да ему не должно быть никакого дела до других потоков, за исключением основного, если он полезет еще и в VCL ! Ему сказано - вызови к выполнению таку-то ХП - вот пусть он только этим и занимается .. А абитражом должен заниматься совсем другой поток, тот самый который заведует общим списком заданий.

with TADOStoredProc.Create(nil) do
try
  CommandTimeout := 0;
  CursorLocation := clUseServer;
  Connection     := _Connection; // ждут тебя здесь грабли, ибо коннекшн создан у тебя совсем в другом потоке


 
Медвежонок Пятачок ©   (2011-11-29 13:46) [67]

TMyThread = class(TThread)
private
  { Private declarations }
 _ADOQuery     : TADOCommand;
 _Connection   : TADOConnection;
public
  _ProcNames: TStrings;


 
YURY   (2011-11-29 13:47) [68]

Я потому и обратился сюда, ибо, видимо, не умею программировать. Умел бы - сделал бы без вопросов. Но никто так и не указал где конкретно ошибка и почему она происходит. Не поняв этого, я еще долго буду биться в пустых Сизифовых попытках. Но в любом случае спасибо тем, кто указывает на мои глупости и неумения. Было бы хуже, если бы попросту проигнорировали.


 
DiamondShark ©   (2011-11-29 13:48) [69]


> Но никто так и не указал где конкретно ошибка и почему она происходит.

Ты троль.


 
Медвежонок Пятачок ©   (2011-11-29 13:48) [70]

// ждут тебя здесь грабли, ибо коннекшн создан у тебя совсем в другом потоке

Да не, это у него так, - для примера, для простоты.
А на самом деле реальный код совсем другой и он идеален и совершенен.


 
YURY   (2011-11-29 13:50) [71]

Сергей М., граблей не наблюдается. Я привёл реально работающий поток, который прекрасно показывает себя при параллельной работе нескольких десятков хранимок в бою.


 
sniknik ©   (2011-11-29 13:50) [72]

> А абитражом должен заниматься совсем другой поток, тот самый который заведует общим списком заданий.
нафига? если уж выбирать такой путь (тупой если честно), то ничего не нужно дополнительно, просто в поток нужно передавать не 1 значение на выполнение, а список, и пусть "крутится" пока список не кончился. одно там выполнение, или два, или десяток подряд неважно, все решается анализом (из БД?) и подготовкой перед "на выполнение".


 
Медвежонок Пятачок ©   (2011-11-29 13:52) [73]

Я привёл реально работающий поток, который прекрасно показывает себя при параллельной работе нескольких десятков хранимок в бою.

Все!
Остановись и ничего не трогай!
Пусть так и работает.


 
Сергей М. ©   (2011-11-29 13:55) [74]


> никто так и не указал где конкретно ошибка и почему она
> происходит


Она происходит потому что :

if Assigned(ptrThread) then // это условие всегда истинно
// в этот момент другой поток потенциально завершает свое выполнение и убивает сам себя, ибо FreeOnTerminate = True
 ptrThread^.WaitFor; // а здесь ты получаешь граблями, потому как обращаешься к трупу


 
Anatoly Podgoretsky ©   (2011-11-29 13:58) [75]

> YURY  (29.11.2011 13:18:56)  [56]

Какие выберет не знаешь, но откуда то знаешь какие при этом параметры
указывать. Странно это.


 
Anatoly Podgoretsky ©   (2011-11-29 14:02) [76]


> YURY   (29.11.11 13:47) [68]

Сними очки или позови кота, мы ему все еще раз объясним.


 
Anatoly Podgoretsky ©   (2011-11-29 14:02) [77]


> Медвежонок Пятачок ©   (29.11.11 13:48) [70]

Кривые примеры нам не нужны


 
Anatoly Podgoretsky ©   (2011-11-29 14:05) [78]

Чувствую, что скоро придется тему закрывать из-за бесперктивности или посылать в Потрепаться.


 
YURY_   (2011-11-29 14:08) [79]

Anatoly Podgoretsky, список параметров хранимок я получаю сам, а значения параметров пользователь задаёт через интерфейс. Эти значения я считываю запросом. В только что приведённом рабочем потоке видно, как эти значения отыскиваются в зависимости от имени хранимки и заполняют её параметры.


 
YURY_   (2011-11-29 14:11) [80]

Сергей М., почему к трупу? Ведь в примере с VCL второй поток не стартует совместно с первым, а именно ожидает несколько секунд, пока первый не отработает. Т.е. Ожидание завершения происходит, но по какой-то причине не происходит возобновление работы второго потока.



Страницы: 1 2 3 вся ветка

Текущий архив: 2012.03.11;
Скачать: CL | DM;

Наверх




Память: 0.64 MB
Время: 0.01 c
15-1321821005
Юрий
2011-11-21 00:30
2012.03.11
С днем рождения ! 21 ноября 2011 понедельник


15-1321514725
DelphiN!
2011-11-17 11:25
2012.03.11
Сервер для хранения приложений для запуска их на клиентах


2-1322663788
_qwerty_
2011-11-30 18:36
2012.03.11
организация работы с таблицами


2-1322574176
Цукор5
2011-11-29 17:42
2012.03.11
Передача структуры с типом String


2-1322563453
Vyacheslav
2011-11-29 14:44
2012.03.11
Теория: Как эта функция отдаёт константы?