![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
leg501 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 31.1.2008 Репутация: нет Всего: 1 |
Сдраствуйте господа. есть такая проблемка
1)есть поток в нем есть массив его содержимое изменяет функция 2)есть второй поток который должен выцеплять данные по не которому условию из этого массива (условие цеплять или нет))) пробую писать так поток которы й выцепляет
поток изменения масива
собственно задача сводится к большему но ключевой момент это доступ к массиву из другого места(модуля\потока) пробывал var параметр на массив но что то переопределенный конструктор нехочет Это сообщение отредактировал(а) leg501 - 7.7.2008, 11:07 |
||||
|
|||||
Virtuals |
|
||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 476 Регистрация: 27.11.2006 Репутация: 3 Всего: 11 |
несколько основных моментов:
1. буфер данных при использовании в разных потоках обьявляется снаружи тоесть (кстати в обьявлении у вас ошибка ![]()
2. инициализировать буфер ДО старта потоков 3. далее доступ к данным в Buffer из обоих потоков ТОЛЬКО через метод Synchronize!!! 4. ну и как пользовать
Это сообщение отредактировал(а) Virtuals - 7.7.2008, 13:32 |
||||
|
|||||
leg501 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 31.1.2008 Репутация: нет Всего: 1 |
Тоесть вы предлагаете иползовать глобальный массив для обоих потоков ,но тогда зачем нужно будет вызов данных через указатель , я ведь и так смогу обратится напрямую с массиву или я неправ.
просто есть похоий код на с++ и там через указатель я могу считать любое данное смещая его на нужный индекс в делфи увы так не получается или я незнаю как это провернуть. |
|||
|
||||
Virtuals |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 476 Регистрация: 27.11.2006 Репутация: 3 Всего: 11 |
leg501,
ну еще раз! А. данные используемые в разных потоках, ну просто обязанны быть снаружи! Б. соответственно память под эти данные обязана быть выделенной до, использования ее в потоке В. требуется исключить любую возможность асинхронного доступа к данным из разных потоков (имелось ввиду что один поток пишет вторую половину данных, в то врея когда другой читает первую половинку,- упрощенный пример, а еще хуже когда 2 потока пытаются заисать в одну и ту же область) просто почитайте про Synchronize, думаю станет поятно зачем это //идио... пример: поток 1 записал в буфер: "маша дэфка" поток 2 читает буфер "маша" поток 1 пишет в буфер "петя пасан" поток 2 дочитывает буфер " пасан" итог: у поток 2 буфер = "маша пасан" ![]() ![]() Добавлено через 3 минуты и 59 секунд а вызов через указатель- а его почти всегда можно передать, в отличии от чего другого, + можн память выделять ка изнутри, так и извне /ну типа: слыш процедур, пишика по этому адресу, в том формате, о котором мы с тобой вкурсе/ ![]() ![]() ![]() Добавлено через 13 минут и 1 секунду leg501, а вот насчет указателей, есть способы читать любое смещение относительно адреса, а вот по сравнению с C как вам такое
![]() |
|||
|
||||
Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
Через типизированный указатель в Delphi еще лучше чем на плюсах, можно к указателю применить Inc и Dec и это будет смещать его на размер базового типа. Ну или всякие преобразования указателя к целому.
Впрочем если есть массив, то что мешает обращаться к нему просто по индексам? А Synchronize по-моему нужен для работы с визуальными компонентами, в принципе всегда можно применить блокировку, так чтобы работал с буфером только поток ее установивший. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. ![]() Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
Virtuals |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 476 Регистрация: 27.11.2006 Репутация: 3 Всего: 11 |
нет не только для визуальных, это очень расспространенное заблуждение. тема синхронизации потоков древняя и по ней достаточно много написано. в принципе всегда можно применить блокировку, так чтобы работал с буфером только поток ее установивший. - все правильно но!!! флаг блокировки взводить и проверять только через Synchronize (в частном случае) Synchronize - заставляет "вынырнуть" из потока, в поток родитель! ЗЫ в своих приложениях всегда стараюсь пользовать Synchronize, это дает достаточно простой способ, не наступить на грабли с доступом к данным при межпоточном взаимодействии! ну вот еще маленький примерчик баловства с указателями
Это сообщение отредактировал(а) Virtuals - 8.7.2008, 09:55 |
|||
|
||||
Rrader |
|
|||
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 70 Всего: 191 |
В методе, вызываемом с помощью Synchronize, может быть любой код, в том числе и потоко-небезопасный код VCL. Synchronize - это просто удобное средство синхронизации. Синхронизировать VCL с помощью обычных методик тяжело. Но за все следует платить - вызовы Synchronize увеличивают нагрузку на основной поток. Virtuals, в подобного рода задачах (асинхронный доступ к данным из разных потоков, не работающих с VCL) использовать Synchronize совершенно неэффективно. Не стоит использовать сложные методы синхронизации там, где этого не нужно. Достаточно обойтись критической секцией и получить максимальную производительность.
Это сообщение отредактировал(а) Rrader - 8.7.2008, 18:12 |
|||
|
||||
Virtuals |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 476 Регистрация: 27.11.2006 Репутация: 3 Всего: 11 |
Rrader,
unit Classes; ничего не напоминает? ![]()
не спорю что просто критическая секция помогает и значительно быстрее, но увы не всегда поймеш где нарвешся на проблемы, а вот SyncProc.Signal использовать это один из простых, хоть и медленных способов, так зачем изобретать велосипед, в большинстве случаев достаточно и производительности Synchronize Это сообщение отредактировал(а) Virtuals - 9.7.2008, 06:13 |
|||
|
||||
Rrader |
|
|||
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 70 Всего: 191 |
В данной задаче не нарвешься. Нужно строить эффективный код, когда эта возможность и так на блюдечке ![]() |
|||
|
||||
leg501 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 31.1.2008 Репутация: нет Всего: 1 |
Спасибо за повторное обьяснение и привидение примеров так сказать на пальцах это помогло представить задачу немного в другом свете и решить таки ее .
Доступ к данным через указатель и смещение его inc и dec оказалось не так удобно как глобальный масив ю Чтож бдем учится языку и его фитчам незря же люди есть готовые помочь начинающим. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |