![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
---|Ветка была без названия|---
ki11er © (2003-03-04 21:11:00)приведенный ниже код валится через пару минут работы с сообщениями "Index is out of date" или "Insufficient Memory..." (при 256 оперативки и паре свободных гигах на винте ;-))))
При написании следовал советам, полученным в этой конференции, а так же из других источников. Можно ли написать подобный код так, чтобы он работал без глюков или это принципиально невозможно?
procedure TFormMain.FormCreate(Sender: TObject);
var i: integer;
str_tmp: string;
begin
StartDir := ExtractFilePath(Application.ExeName);
if StartDir[Length(StartDir)] <> "\" then begin
StartDir := StartDir + "\";
end;
sDirDB := StartDir + "dbase\";
CreateDir(sDirDB);
CreateDir(StartDir + "net");
Session.NetFileDir := StartDir + "net";
CreateDir(StartDir + "private");
str_tmp := StartDir + "private\" + IntToStr(GetTickCount);
CreateDir(str_tmp);
Session.PrivateDir := str_tmp;
tbTest.DatabaseName := sDirDB;
qrTest.DatabaseName := sDirDB;
btnStartStop.Caption := "
ki11er (2003-03-12 19:13:00) [1]
> Попробуй inherited Create(True);
> ...
Был и такой вариант...
А что это меняет? Насколько я понимаю, - ничего.
Serginio (2003-03-12 18:59:00) [2]Попробуй inherited Create(True);
А затем
for i:=0 to 10 do begin
TableThreads[i].resume
end;
ki11er (2003-03-12 18:31:00) [3]
> Ты утверждаешь что у тебя все правильно - аргументируй.
8-O Где? Где Вы это прочитали/увидели/услышали?
Я только лишь говорю, что в соответствии с хелпом и др. документами(см. выше). Но раз неработает, - значит что-то неправильно. Но что?
> "Ты хоть попробовал синхронизировать потоки???"
Засинхронизировать потоки не составляет труда. Думаю, при этом станет работать более стабильно (насколько более - не известно, возможно даже сбоев вообще не будет). Но это будет другое решение другой задачи.
> Бде закрытая система и многие вещи познаются путем проб
> и ошибок как в твоем случае .
Я пока что стараюсь следовать тому, что написано в документации... Возможно потом придется заняться "шаманством", если нормальные способы не помогут.
Serginio (2003-03-12 17:58:00) [4]Бде закрытая система и многие вещи познаются путем проб и ошибок как в твоем случае . Принцип понятен, а как конкретно это реализовано в BDE тебе никто не скажет кроме самих разработчиков.
Еще раз спрошу "Ты хоть попробовал синхронизировать потоки???"
Mike Kouzmine (2003-03-12 17:53:00) [5]По законам дискусси, утверждающая сторона должна приводить свои аргументы. Ты утверждаешь что у тебя все правильно - аргументируй. А то получается "У вас синий нос, докажите что не синий, ну не синий, а зеленый, докажите, что нет"
Ты расслабся и избавься от своей идеи фикс, а то, что она фикс, ясно всем, кроме тебя. И взгляни на проблему с другой стороны.
Проще будет.
ki11er (2003-03-12 17:42:00) [6]
> Посмотри для пимера как устроены индексы
> http://www.1c.hippo.ru/cgi-bin/predownl.cgi?id=2019
Я представляю, как могут быть устроены индексы. Но в данном случае меня интересуют не индексы вообще, а как это реализовано в BDE в частности (формат файла и код, который с этим работает)
> И станет ясно, что критическим является перестроение Индекса.
Я ж сказал, что не спорю. Пусть будет критическим ;-) Но отсюда совсем не следует, что все должно валиться...
ki11er (2003-03-12 17:15:00) [7]
> Основное правило корректной работы многозадачныхсистем
> - задачи должны быть разделены по данным, памяти и управлению.
>
> Ты в свой программе нарушил все три этих правила.
Ага, в одной задаче нарушил все правила многозадачности :-D
Да будет Вам известно, что потоки внутри процесса работают в одном адресном пространстве.
Замечания о том, что я нарушил прошу форматировать так:
строка кода
описание, что нарушено(какие правила, и т.п.)
источник информации(хэлп, мануал, ...), место в источнике, где про это написано(объясняется как надо/не надо делать)
Serginio (2003-03-12 17:14:00) [8]Посмотри для пимера как устроены индексы
http://www.1c.hippo.ru/cgi-bin/predownl.cgi?id=2019
И станет ясно, что критическим является перестроение Индекса.
А написано ЗДЕСЬ. Ты хоть попробовал синхронизировать потоки???
Soft (2003-03-12 16:56:00) [9]To Killer
Основное правило корректной работы многозадачных систем - задачи должны быть разделены по данным, памяти и управлению.
Ты в свой программе нарушил все три этих правила.
ki11er (2003-03-12 16:13:00) [10]2 Serginio:
> Про SQL почему ты думаешь, что на сервере не испльзуются
> критические секции и тому подобное.
Я так и не думаю... С чего ты взял?
> Еще раз повторю, что при записи лимитирующей стадией является
> перестроение индекса.
Я не спорю, возможно. Но где про это написано?
ki11er (2003-03-12 16:05:00) [11]2 Soft:
> Что такое школа Ю.Зотова?
Не знаю, и в принципе не особо хочу знать
> При многопоточности во время обращения к базе помогает метод
> Synchronize (почитай в хелпе TThread). При использовании
> данного метода происходит переключение в однопоточность
> на время работы процедуры и глюки просто исчезают.
"Переключение в однопоточность" - это круто ;-)))
Посмотри на досуге, как на самом делеработает Synchronize. Лично у меня в правилах записано, не использовать эти вызовы, кроме случаев, когда это действительно необходимо. Боюсь, опять завяжется пустой спор, но imho использование sinchronize чревато последствиями.
> Killer ты или гений который произведет революцию в программировании
> или полный идиот. Эти две крайности различает только успех.
флейм
> Советую читать не книги а хелпы, мануалки, высказывания
> людей... Слушай всех, выбирай сам
Спасибо, конечно, за совет. ;-)
Serginio (2003-03-12 15:48:00) [12]Про SQL почему ты думаешь, что на сервере не испльзуются критические секции и тому подобное. Как раз скорей всего и используются это дешевле и намного ускоряет работу. Еще раз повторю, что при записи лимитирующей стадией является перестроение индекса. Если не запретить одновременный доступ к таблицам с одинаковым индексом то получишь,что у тебя. А в разные таблицы ты и на локальных машинах пиши сколько душе угодно.
Soft (2003-03-12 15:25:00) [13]Привет.
1) Что такое школа Ю.Зотова?
2) При многопоточности во время обращения к базе помогает метод Synchronize (почитай в хелпе TThread). При использовании данного метода происходит переключение в однопоточность на время работы процедуры и глюки просто исчезают.
3) Если хочешь чтоб за тебя многопоточность обрабатывала БД то юзай полный SQL сервер(IB, Oracle, ASA, MS Sql ....)
4) Killer ты или гений который произведет революцию в программировании или полный идиот. Эти две крайности различает только успех.
5) Советую читать не книги а хелпы, мануалки, высказывания людей... Слушай всех, выбирай сам
ki11er (2003-03-12 13:53:00) [14]
> а Как ты представляешь паралельную запись в файл
Ну, если дойти до уровня головок/секторов/цилиндров и при условии, что у нас один обыкновенные винчестер, то imho никак.
Но если так рассуждать, то и самый навороченный SQL тоже пишет последовательно ;-))), однако при этом не валится ;-)
Serginio (2003-03-12 12:30:00) [15]Беда локальных БД в том, что одновременное чтение и запись влияют на результаты чтения. Для того, чтобы прочитанные данные были абсолютно верны на конец чтения надо прменять MultiReadExclusiveWriteSinchronizer.
Скорее я и не прав на счет "Однозначно BDE не следит за записями в файл", но у меня такой вопрос
а Как ты представляешь паралельную запись в файл??? Она может быть только последовательной!!!. А применяя синхронизацию ты облегчаешь задачу BDE так как ей не нужно следить за блокировками на уровне файловой системы и возможными при этом задержками и инертностью.Плюс не исключены разного рода ошибки в BDE. Делай выводы
ki11er (2003-03-11 21:18:00) [16]2 Serginio:
> 1. "Однозначно BDE не следит за записями в файл" доказательство
> твоей ситуации
Делать какие-то выводы, imho, преждевременно.
> 2.Блокировки идут на уровне файлов. Читай посты.
Какие конкретно? В свою очередь могу посоветовать почитать что-нибудь про *.net и *.lck файлы.
> 3. Если ты попрбуешь использовать MultiReadExclusiveWriteSinchronize то у тебя все должно прекрасно получиться
Возможно, но мне все же интересно, как сделать параллельный доступ. К томуже, того же результата можно добиться и крит. секцией.
Serginio (2003-03-11 20:54:00) [17]1. "Однозначно BDE не следит за записями в файл" доказательство твоей ситуации.
2.Блокировки идут на уровне файлов. Читай посты.
3. Если ты попрбуешь использовать
MultiReadExclusiveWriteSinchronize то у тебя все должно прекрасно получиться. Если не влом проверь и сообщи о результатах.
ki11er (2003-03-11 20:06:00) [18]2 Dred2k:
Работает уже около полугода. Выявлены интересные особенности движка бде (но это - уже другая история ...). ;)
Можешь рассказать, что это за особенности? (можно на мыло)
ki11er (2003-03-11 19:07:00) [19]2 Serginio:
Повторю вопрос: "Где это написано?" и могу добавить еще один:
"Зачем тогда сделаны все эти заморочки с файлами блокировки и т.п.? Не думаю, что это нужно для совместного чтения".
2 Dred2k:
у меня так:
_FSession := Sessions.OpenSession("Session" +
IntToStr(integer(@_FSession)) +
IntToStr(GetTickCount));
GetTickCount - для защиты от возможной ситуации, когда в двух запущенных копиях программы случайно совпадут (@_FSession).
> Только учти - у БиДЕ есть ограничения на всякие ресурсы,
> типа баз, сессий и курсоров ->
Это я уже понял. Ограничения есть, причем на первый взгляд ничем не оправданные :( Но с этим еще можно как-то смириться...
Вариант с DataBase я тоже пробовал. Результат аналогичный. Пока что работаю с TTable, вариант c TQuery ждет своей очереди (мне тут неоднократно говорили, что TTable и TQuery - один фиг, хотя я конечно не очень в это верю).
Dred2k (2003-03-11 18:03:00) [20]Для каждого TQuery/TTable, используемого в отдельном потоке - своя пара TDatabase/TSession. С уникальными именами (GetTickCount точно не катит - лучше уж IntToStr(Integer(созданный объект))).
FDB := TDatabase.Create(nil);
FSession := TSession.Create(nil);
FQuery := TRxQuery.Create(nil);
FSession.SessionName := "SESSION" + IntToStr(Integer(FSession));
FDB.AliasName := "NVTEST"; // К примеру
// ... или настраивайешь ручками через DriverName := и все такое ...
FDB.DatabaseName := "DB" + IntToStr(Integer(FDB));
FDB.SessionName := FSession.SessionName;
with FQuery do begin
SessionName := FDB.SessionName;
DatabaseName := FDB.DatabaseName;
SQL.Clear;
SQL.Add("");
end;
Дальше в нити делай с FQuery что душе угодно. И будет тебе счастье ...
Только учти - у БиДЕ есть ограничения на всякие ресурсы, типа баз, сессий и курсоров -> http://www.delphikingdom.com/asp/answer.asp?IDAnswer=6280