Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 012

/ вопрос открыт /

Здравствуйте, уважаемые эксперты!

Есть не большой вопрос от ламера: есть поток TServerThread, данные принимаются с определенного порта, обрабатываются в этом потоке. При обработке информации используются функции описаные в этом эе юните. Так вот вопрос - будут ли конфликты по обработке переменных этими функциями (переменные не глобальные, создаются в самом потоке). Т.е. если один поток послал в функцию исходное значение то может ли другой поток, уже использующий эту функцию, получить не свои выходные параметры. Или это все решается само по себе. Единственный общий компонент у всех потоков - поле Memo, для вывода отладочной информации (это временно).

Димчик Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Димчик (статус: Посетитель)
Вопрос отправлен: 11 апреля 2010, 14:52
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 6; последнее сообщение — 20 апреля 2010, 08:03; участников в обсуждении: 4.
min@y™

min@y™ (статус: Доктор наук), 11 апреля 2010, 16:12 [#1]:

Посоветовать ничего здесь не могу, ибо никогда так не делал. Но, имхо, использование глобальных переменных с потоками - это аццкий гимарой, который ведёт к раку мозгов.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Димчик

Димчик (статус: Посетитель), 11 апреля 2010, 20:57 [#2]:

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

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

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 12:01
Выполнено за 0.03 сек.