Форум: "Начинающим";
Текущий архив: 2012.03.11;
Скачать: [xml.tar.bz2];
ВнизПотоки Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.62 MB
Время: 0.006 c