|
Вопрос # 4 012/ вопрос открыт / |
|
Здравствуйте, уважаемые эксперты!
Есть не большой вопрос от ламера: есть поток TServerThread, данные принимаются с определенного порта, обрабатываются в этом потоке. При обработке информации используются функции описаные в этом эе юните. Так вот вопрос - будут ли конфликты по обработке переменных этими функциями (переменные не глобальные, создаются в самом потоке). Т.е. если один поток послал в функцию исходное значение то может ли другой поток, уже использующий эту функцию, получить не свои выходные параметры. Или это все решается само по себе. Единственный общий компонент у всех потоков - поле Memo, для вывода отладочной информации (это временно).
 |
Вопрос задал: Димчик (статус: Посетитель)
Вопрос отправлен: 11 апреля 2010, 14:52
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 6; последнее сообщение — 20 апреля 2010, 08:03; участников в обсуждении: 4.
|
min@y™ (статус: Доктор наук), 11 апреля 2010, 16:12 [#1]:
Посоветовать ничего здесь не могу, ибо никогда так не делал. Но, имхо, использование глобальных переменных с потоками - это аццкий гимарой, который ведёт к раку мозгов.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Димчик (статус: Посетитель), 11 апреля 2010, 20:57 [#2]:
переменные как раз не глобальные, в потоке свои переменные.
меня больше интересует, если сразу два потока обратятся к одной функции - будут проблемы или нет, может ли один поток получить выходные данные функции другого потока.
|
|
IlluminatI (статус: 2-ой класс), 11 апреля 2010, 21:46 [#3]:
Сомневаюсь, если не ошибаюсь, делфи создаст уникальную копию подпрограммы для каждого вызова - рекурсия же работает.
|
|
Димчик (статус: Посетитель), 11 апреля 2010, 22:15 [#4]:
тогда спаибо - по этому поводу больше вопросов нет
а вот если в потоке есть insert в БД, параметры запроса устанавливаются в потоке, т.е. например в одном потоке id=12, а в другом id=13 - будут ли конфликты в этом случае. Получится что один поток установил параметры - второй установил новые параметры - первый поток выполнил запрос - второй поток опять выполнил этот же запрос - получится что один insert будет два раза. Или я не прав. Может перед установкой параметров запроса lock делать?
|
|
Вадим К (статус: Академик), 12 апреля 2010, 10:42 [#5]:
По поводу базы - всё зависит от того, как осуществляется добавление. Можно сделать так, что проблем будет.... не оберешся. А можно и без них. По описанию понять как все происходит - невозможно. К тому же "драйвер базы данных" - тот код, который обеспечивает связь с базой, должен уметь работать с несколькими потоками.
Если же страшно очень, что может быть ЧП, советую изучить TCriticalSection
По поводу функций.
Локальные параметры потокобезопасны. Пока функции не обращаются к внешним ресурсам, глабальным переменных, записи в файл, то проблем с ними не будет.
В целом, лучше приводить сомнительные функции/процедуры, а мы тут уже попробуем посмотреть.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Димчик (статус: Посетитель), 20 апреля 2010, 08:03 [#6]:
Извините что пропал, закрутился.
К нашему вопросу: сейчас у меня в потоке выставляются параметры запроса и происходит сам INSERT (ну или UPDATE) вот так-
procedure TServerThread.ClientExecute;
var
.
.
.
//это первый запрос - SELECT
Form1.ZReadOnlyQuery1.Params.ParamValues['id']:=id;
Form1.ZReadOnlyQuery1.Active:=true;
.
.
.
//это уже INSERT
form1.ZQuery1.Params.ParamValues['d1']:=d1;
form1.ZQuery1.Params.ParamValues['d2']:=d2;
form1.ZQuery1.Params.ParamValues['d3']:=d3;
form1.ZQuery1.Params.ParamValues['id']:=id;
form1.ZQuery1.ExecSQL;
form1.ZQuery1.ApplyUpdates;
.
.
.
//ну и т.д.
Получается, что каждый запрос нужно засунуть в отдельную процедуру с параметрами, а в каждой процедуре использовать свою критическую секцию, вот так, например:
procedure insert(d1,d2,id:integer)
begin
section_insert.enter; //section_insert - глобальная переменная типа tcriticalsection
form1.ZQuery1.Params.ParamValues['d1']:=d1;
form1.ZQuery1.Params.ParamValues['d2']:=d2;
form1.ZQuery1.Params.ParamValues['id']:=id;
form1.ZQuery1.ExecSQL;
form1.ZQuery1.ApplyUpdates;
section_insert.leave;
end
Правильно?
p.s. А как узнать результат INSERT'а - успешно или ошибка?
p.s. Драйвер БД - Zeos
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|