Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
4 / 3 / 1
Регистрация: 23.12.2013
Сообщений: 39
RAD XE3+

Можно ли обратиться из двух разных потоков к полям другого класса?

18.12.2023, 00:03. Показов 2063. Ответов 32
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Имеется ПОТОК1 и ПОТОК2 (TThread). Есть Класс1 отнасследованный от TObject.
Суть в том что в Потоке1 происходит заполнение Поля Класс1.msg1. Далее Поток1 делает синхронизацию Вызывает метод Класс1.Sync в данном методе по мере необходимости происходит копирование Класс1.msg2 := Класс1.msg1;
ПОТОК2 Обрабатывает то что находиться Класс1.msg2, но это делает тогда когда точно не происходит Копирования msg1 в msg2. Т.е. одновременного обращения записи/чтения к одному и тому же полю из разных потоков класса1 отсутствует. Но мне не понятно, могу ли я вообще обращаться к одному классу из разных потоков? Это может привести к какой-то ошибке? Или все таки нельзя обращаться к одному классу из двух потоков, даже если поля разные?.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.12.2023, 00:03
Ответы с готовыми решениями:

Возможно ли члену класса обратиться к полям другого класса в котором он находится?
Есть, к примеру, код: enum TYPE{/*...*/}; class A { uint64_t data; }; class Column { std::vector<A> data;

Обратиться к полям текущего класса из методов другого
Создать два класса - в первом объявить несколько полей в private секции. Обратиться к этим полям из методов второго класса. Один класс...

Как можно обратиться к wpf контролам из другого класса
<Grid Margin="5"> <TextBlock x:Name="speed_xaml" HorizontalAlignment="Left" Margin="10,7,0,0" TextWrapping="Wrap" Text=""...

32
Модератор
4155 / 2364 / 814
Регистрация: 15.11.2015
Сообщений: 9,501
07.07.2024, 14:38
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Иван Ежик Посмотреть сообщение
Менеджер памяти может переписать в любое время адрес по этому указателю (если ему понадобится перенести объект фактически в непрерывный участок памяти)?
С чего бы вдруг? Адрес объекта сам по себе не меняется. Если бы он менялся, то программа просто не могла бы знать, когда это произошло и какой теперь адрес у объекта.
0
57 / 52 / 5
Регистрация: 18.11.2018
Сообщений: 295
07.07.2024, 15:02
Цитата Сообщение от AzAtom Посмотреть сообщение
Адрес объекта сам по себе не меняется
А вот именно поэтому я и начал задавать вопросы.
Экземпляр имеющий внутри себя динамический массив, сменит только указатель на "конкретное измерение" если ему не будет хватать непрерывной памяти?
Либо если это что-то "самодельное", на основе статических массивов(для скорости) и требует переинициализации при изменении размеров(конечно пример немного притянут, но мы в фоне сначала скопируем все поля объекта в текущем их состоянии, а потом заменим ссылку на него)?

Я вообще к тому что гарантии никто не даёт, и доступ к указателю на экземпляр никто не советует разграничивать крит. секцией, ибо тогда все плюсы многопоточности потеряются...
но потоки таки читают начальный адрес экземпляра по указателю?
Если мы руками не прописываем запомнить в локальной переменной потока нужный адрес, то каждый раз будет чтение указателя на экземпляр класса не защищённое крит. секцией?
0
Модератор
4155 / 2364 / 814
Регистрация: 15.11.2015
Сообщений: 9,501
07.07.2024, 16:17
Цитата Сообщение от Иван Ежик Посмотреть сообщение
Экземпляр имеющий внутри себя динамический массив, сменит только указатель на "конкретное измерение" если ему не будет хватать непрерывной памяти?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type
  TIntArray = array of integer;
 
procedure TForm1.SomeProc(a2: TIntArray);
begin
 
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a: TIntArray;
begin
  SomeProc(a);
end;
Тут да, передаётся адрес данных, который может измениться при изменении размера массива.

Но если сделать
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type
  PIntArray = ^TIntArray;
  TIntArray = array of integer;
 
procedure TForm1.SomeProc(a2: PIntArray);
begin
 
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  a: TIntArray;
begin
  SomeProc(@a);
end;
то будет передан адрес переменной a: TIntArray; который уже содержит адрес данных. И даже если поменять размер массива, то доступ к данным останется. Ну и обращаться к массиву нужно через синхронизацию, конечно, а то не исключена смена адреса массива во время обращения к нему потока. Тогда хорошо, если выскочит AV.
1
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
07.07.2024, 18:00
верно
продолжая аналогию с адресами, надо иметь не сам адрес, а место, где этот адрес будет лежать, в случае когда путешественник часто переезжает, но адрес своего текущего места хранит где-то и уже вот это место точно не меняется

и еще раз - менеджер не может ничего поменять сам
только по команде
0
57 / 52 / 5
Регистрация: 18.11.2018
Сообщений: 295
07.07.2024, 18:38
Цитата Сообщение от krapotkin Посмотреть сообщение
и еще раз - менеджер не может ничего поменять сам
только по команде
но есть всякие моменты навроде мы берём хендл битмапа и делаем там что-то напрямую ковыряясь в битах картинки.
Но стоит вызвать ф-цию канваса, и хендл уже invalid поскольку менджер памяти перевыделил её, а мог бы подставить по прежнему указателю или обновить его.
тут уже я не берусь судить насколько это правильно... вроде на ровном месте затраты на выделение новых адресов и удаление старых.

Добавлено через 3 минуты
Цитата Сообщение от Иван Ежик Посмотреть сообщение
тут уже я не берусь судить
Эта тема слишком глубока и затрагивает вопросы того чем руководствовались разработчики на момент разработки, что несомненно не может соответствосать ожиданиям других разработчиков.
0
Модератор
4155 / 2364 / 814
Регистрация: 15.11.2015
Сообщений: 9,501
07.07.2024, 18:53
Цитата Сообщение от Иван Ежик Посмотреть сообщение
Но стоит вызвать ф-цию канваса, и хендл уже invalid
Дельфийский Canvas это довольно таки "вещь в себе". Может и пересоздаёт битмап при некоторых операциях, не знаю. По крайней мере, при работе с ним нельзя надеяться, что какой-то хэндл будет вечным.

Цитата Сообщение от Иван Ежик Посмотреть сообщение
менджер памяти перевыделил её, а мог бы подставить по прежнему указателю или обновить его.
Не мог бы. Менеджер памяти просто выделяет кусок памяти и возвращает её адрес, а обновлять эти адреса должна уже программа сама в своих же переменных.
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
07.07.2024, 19:31
Цитата Сообщение от Иван Ежик Посмотреть сообщение
мы берём хендл битмапа
не путаем теплое с мягким
handle - это ID системного(!) ресурса, которым оперирует ОС
Поэтому для операций, где важна консистентность, мы обязаны его ЗАПРОСИТЬ(ЗАЛОЧИТЬ)! и ОТПУСТИТЬ!
В данном случае МП по отношению к ОС ведет себя как программа по отношению к МП.
При этом ОС залоченную память тоже не сменит. И залоченный хендл не поменяет.

МП берет большие куски памяти у ОС, получая на них хендлы, и потом отдает. Медленно.
А нам выдает по требованию. Быстро.
Вот все для чего он нам нужен.
Но сам ничего поменять не может
1
57 / 52 / 5
Регистрация: 18.11.2018
Сообщений: 295
08.07.2024, 13:28
Цитата Сообщение от krapotkin Посмотреть сообщение
Но сам ничего поменять не может
Но если попробовать пример с "доступом к памяти битмапа напрямую, а потом нарисовать на нём средствами канваса", то при следующем доступе напрямую будет AV...Кто-то поменял его расположение в памяти, хотя размер битмапа не поменялся.
Цитата Сообщение от krapotkin Посмотреть сообщение
не путаем теплое с мягким
Да, я ошибся в формулировке, имел в виду прямой доступ к памяти картинки

Добавлено через 4 минуты
Цитата Сообщение от AzAtom Посмотреть сообщение
Ну и обращаться к массиву нужно через синхронизацию, конечно, а то не исключена смена адреса массива во время обращения к нему потока.
Так а с экземплярами класса это как работает? Я к тому что рекомендуют синхронизировать доступ к полям но не к самой переменной экземпляра(которая являясь ссылочным типом по сути и есть указатель, но который не может быть изменён с помощью арифметики указателей)

Добавлено через 1 минуту
Цитата Сообщение от AzAtom Посмотреть сообщение
По крайней мере, при работе с ним нельзя надеяться, что какой-то хэндл будет вечным.
Я ошибся, не хендл имел в виду а доступ к памяти картинки...
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
08.07.2024, 14:36
Память картинки, если эта картинка - системный ресурс (а в VCL это именно так) - закрыта
Поэтому берем хендл и далее по списку...
В частности, потому что все форматы и JPEG и PNG ложатся в единый системный bmp, с которым GDI только и умеет работать.

В FMX уже ввели TBitmapSurface - там просто голые данные, никто их не заберет.

Цитата Сообщение от Иван Ежик Посмотреть сообщение
рекомендуют синхронизировать доступ к полям
Рекомендации не бывают исчерпывающими.
Нужен контекст
У каких-то объектов поля все время текут
Например List будет все время изменять свой внутренний массив, т.е. ссылка на него будет меняться
поэтому надо лочить сам List, брать массив, делать что-то , отпускать List.

Со строкой, насколько я помню, еще интереснее.
Объект может поменять поле-строку, в этом случае ссылка на нее изменится, но предыдущая ссылка будет содержать старую строку. Без AV.
0
Модератор
4155 / 2364 / 814
Регистрация: 15.11.2015
Сообщений: 9,501
08.07.2024, 14:45
Цитата Сообщение от Иван Ежик Посмотреть сообщение
Я к тому что рекомендуют синхронизировать доступ к полям но не к самой переменной экземпляра
Переменная объекта и называется полем. Не пойму, в чём проблема. Пока существует экземпляр объекта, его поля тоже на месте.

Цитата Сообщение от Иван Ежик Посмотреть сообщение
имел в виду а доступ к памяти картинки
У меня с этим проблем не было. Можно пример с таким эффектом?

При старте программы создал bitmap нужного размера, записал адрес начало битов в свою переменную и затем рисую на этом bitmap как средствами canvas, так и напрямую пишу в память - работает без проблем.
0
57 / 52 / 5
Регистрация: 18.11.2018
Сообщений: 295
08.07.2024, 15:31
Цитата Сообщение от krapotkin Посмотреть сообщение
Память картинки, если эта картинка - системный ресурс (а в VCL это именно так) - закрыта
Поэтому берем хендл и далее по списку...
Но сканлайн с примерами показывает как работать с памятью картинки, и предупреждений не пишет что внутри работает с хендлом.Так же ничто не мешает менять адрес указателя для доступа в нужное место памяти картинки.
(так собственно всё и работает, и до первого косяка вникать что под капотом реализации не нужно )
Цитата Сообщение от AzAtom Посмотреть сообщение
У меня с этим проблем не было. Можно пример с таким эффектом?
Я думаю несколько лет назад это упоминал тут на форуме.
Если коротко то нужно было нарисовать рамку на распознанном на картинке объекте, я долго не мог понять почему появлялись AV...
А сделано было так

begin
Читаем память картинки напрямую, распознаём;
Рисуем рамку или сдвигаем окно если не удалось.
Проверяем некое условие нужно ли повторить и так по кругу.
end

В итоге пришлось изменить на запоминание позиций, и уже потом, после распознования, рисование рамок после всех действий во втором отдельном цикле.
Сам код я не найду но запомнил этот момент навсегда, час потратил наверное на написание десятка разных проверок чтобы понять в чём дело.
Цитата Сообщение от AzAtom Посмотреть сообщение
Переменная объекта и называется полем. Не пойму, в чём проблема. Пока существует экземпляр объекта, его поля тоже на месте.
Так я с этого и начал вчера, и за вчера так никто и не ответил, как будто специально делая вид, что не замечают.
Все 10 условных параллельных потоков могут?! одновременно обратится к указателю на экземпляр класса ведь это не разграничено крит секцией, а если разграничить то не будет многопоточности.
0
Модератор
4155 / 2364 / 814
Регистрация: 15.11.2015
Сообщений: 9,501
08.07.2024, 16:13
Цитата Сообщение от Иван Ежик Посмотреть сообщение
Все 10 условных параллельных потоков могут?! одновременно обратится к указателю на экземпляр класса
Могут, если программист гарантирует, что переменная/поле, содержащая адрес объекта будет жить во время работы этих потоков.

Цитата Сообщение от Иван Ежик Посмотреть сообщение
и за вчера так никто и не ответил, как будто специально делая вид, что не замечают.
А это что?
Цитата Сообщение от AzAtom Посмотреть сообщение
А как поток узнаёт адрес объекта? Обычно, он же передаётся заранее, при создании объекта потока. Вот и будет поток хранить адрес объекта в своей области памяти.
То есть, каждый поток будет считывать адрес объекта из своей собственной области памяти.

Хотя, не вижу препятствий для чтения всеми потоками и из одной переменной, при условии, что эта переменная будет жива всё время работы потоков. Читайте на здоровье, тем более, если эта переменная считывается за одно чтение, то вообще нет проблем.

А вот с тем же динамическим массивом уже нужны меры, а то, пока один поток читает данные, другой поток вздумает изменить размер массива и он "переедет" по другому адресу памяти, тогда, первый поток может получить AV.
1
57 / 52 / 5
Регистрация: 18.11.2018
Сообщений: 295
08.07.2024, 16:38
Цитата Сообщение от AzAtom Посмотреть сообщение
А это что?
Ну там не ответ про 10 потоков ) и если сделать именно так как указано (назначить адрес при создании потока) то гарантированно два потока не смогут одновременно обратится к адресу экземпляра, ведь создание занимает время, поэтому я и не воспринял как ответ про одновременный доступ.

Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.07.2024, 16:38

Как обратиться к полям класса?
Есть класс в котором в полях заданы некоторые параметры, я создал объект (через указатель), но не знаю как выводить его параметры. То есть...

Доступ к полям класса через переменные другого класса
Уважаемые коллеги! Почему в моделях Аnylogic для упрощения доступа к полям одного класса (класс А) вводится в другой класс (класс В)...

Проблема с обращением к полям класса из другого класса
Приветствую. Работаю с WinForms. У меня есть главная форма DefaultForm, побочные формы TakeOffMoney и InsertMoney, и класс Card. На...

Из одного класса обратиться к свойству progressBar из другого класса (основного окна)
Привет! :) Помогите пожалуйста нубу (мне). У меня есть два класса. Первый (основной), его код: namespace CMS { ///...

Как обратиться к значениям переменной одного класса из метода другого класса
Есть переменная - Холодильник1 класса Freezer Холодильник1 = Freezer() Холодильник2 = Freezer() class Freezer: food...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru