![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
Sunvas |
|
|||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Вот есть простой нерабочий код:
В принципе причина неработоспособности ясна - нет синхронизации. Я долго искал но не нашел ничего про синхронизацию потоков созданных при помощи createthread (без класса TThread). Помогите сделать код, преведеный выше, рабочим. ![]() -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
|||
|
||||
Ibragim |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Вопрос не в синхронизации, а в вызове form1.Button2.Click;
Такие финты с визуальными контролами глючат из-под потоков. Можно только SendMessage этому контролу. А так все нормально, нечего здесь синхронизировать IMHO - захотел и удалил ![]() PS Offtop О, сообщение юбилейное 100 ![]() Это сообщение отредактировал(а) Ibragim - 14.12.2006, 00:13 |
|||
|
||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Sunvas, ну уже пора знать про этот топ: http://forum.vingrad.ru/index.php?showtopic=60076
Что касается VCL. Да, нежелательно обращаться из стороннего потока, ибо VCL работает в основном. Но, если защитить синхронизацией, то вполне допустимо. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Sunvas, c VCL нормально синхронизирует только метод Sincronize потомков TThread. Большинство объектов имеют между собой внутренние связи, которые нельзя ограничить, т.е. всегда есть шанс обратиться одновременно из двух потоков к общей памяти.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
alexeis1, ну это ты слишком загнул.
Синхронизацию можно установить всегда. У VCL есть своя специфика. Но не до такой степени... |
|||
|
||||
Sunvas |
|
||||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Я знаю про этот топ. Однако просматривая его я не увидел, чтобы там поток создавался без класса tthread. Может я просто невнимательно читал.. ![]()
Читаем тему внимательней: ![]() -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Sunvas, я это понимаю, но ведь требуется именно синхронизация с VCL, я смотрел этот (Sincronize) и как я понял суть его в том, что в определенный момент (у VCL есть спец. мьютекс позволяющий корректно это делать) останавливается главный поток и второй поток становится за главного и выполняет все нужные операции, после чего он должен разблокировать исходный главный поток. Можно посмотреть как это там реализовано и сделать аналогично, но уже без Thread.
Добавлено @ 20:57 Получается что главный поток большую часть времени владеет VCL мьютексом и в определенные моменты его отдает, второй поток должен ждать этого момента и его захватить. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Вот этот метод класса можно вызывать без того чтобы создавать сам класс и тем самым синхронизироваться с VCL. Не создавая потомка TThread.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Sunvas |
|
|||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Че-то я не врубился как его вызывать... Туплю однако. -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Так же как конструктор. Класс Объект еще не существует а конструктор можно вызывать. Это сообщение отредактировал(а) alexeis1 - 14.12.2006, 23:06 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 31 Всего: 88 |
кроме тех случаев когда это уже как-то мутно сделано и есть шанс получить дедлок
-------------------- Обижено школьников: 8 |
|||
|
||||
Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Да не так уж всё сложно.
Но в данном случае проще нарисовать, чем объяснить ![]() Создаём критическую секцию. В OnIdle отпускаем её, и сразу снова занимаем. Таким образом мы подготовили Application к синхронизации. Теперь нашь поток должен просто занять секцию. Если занял, то основной поток засыпает до тех пор, пока мы не отпустим секцию, и вся VCL работа выполняется уже в нём. После этого отпускаем секцию и её снова получает основной, вместе с управлением. Получается такая вот весёлая секция - кто ей владеет, тот и рулит VCL'ем. Обычно ей владеет основной поток. Но, если он ничем не занят, то рулилку при необходимости может взять второстепенный. |
|||
|
||||
Sunvas |
|
||||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Ну это я давно догадался. Просто не пойму почему Делфи упорно видит исключительно функцию
И не хочет ни в какую видеть ту, что ты написал?? -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
А блин, она в привате ![]() Ну тогда просто сделать процедуру и включить в нее этот код. Он делает по сути тоже, что Snowy сказал, вот только не зачем помещать критическую секцию в OnIdle, потому что одна такая секция, точнее мьютекс похоже уже включена в цикл обработки TApplication. Хорошо бы в этом разобраться. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Alexeis |
|
||||||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
так и есть. Следующий фрагмент взят из функции обработки сообщений класса TApplication
CheckSynchronize; - позволяет блокироваться главному потоку. Вот что про нее сказано в модуле classes
А вот ее фрагмент
Т.е. как видно она зависима от глобальной критической секции ThreadLock Если она занята, то главный поток тут заблокируется. Если вернуться к коду class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord);
То видно, что оба метода используют одну и ту же критическую секцию и могут ее занимать только по очереди. Значит нужно просто дождаться пока она освободиться и затем сразу ее занять. После того как мы ее заняли, то правда нужно будет еще дождаться пока на ней заблокируется основной поток иначе за промежуток времени между тем как второй поток уже занял критическую секцию, а основной поток не вернулся опять и не заблокировался работают одновременно 2 потока паралелльно. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||||
|
|||||||||
Sunvas |
|
|||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
alexeis1, Snowy, спасибо. В теории постепенно начинаю догадываться... Уже прогресс!
![]() Но вот как привязать к синхронизации form1.Button2.Click;? -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Просто ее нужно вызывать только после того как остановлен главный поток. Пока главный поток спит, работает всего один единственный поток, потому он уже ни с кем не конфликтует и можно вызывать все что угодно. Главное потом разбудить спящего ![]() -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Sunvas |
|
||||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Как из-под треда остановить основной поток? Если вызывать эту функцию из потока, то вылазит ошибка. ![]()
Если вытскивать код процедуры в мою процедуру - она перестает работать. ![]() -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Не правильно понял! Эту функцию вызывает основной поток для того, чтобы дополнительный поток мог его заблокировать. Нужно просто войти в указанную критическую секцию и дождаться пока на ней же заблокируется основной поток. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Sunvas |
|
|||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Можешь код нарисовать? А то уже танцую с бубенцом вокруг этой проблемы со вчерашнего дня. -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
|||
|
||||
Alexeis |
|
||||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Оказывается у класса TThread все нужные методы являются методами класса. Вот он метод, который позволит сделать очень просто синхронизацию.
Единственное, неудобство, что ему нужно передавать метод, а не процедуру, но и это на самом деле несложно обойти, но в данном случае не суть. Если первый параметр NIL то синхронизация будет производится с основным потоком. В качестве метода я использовал метод формы.
BeginTreadClick - создает поток и запускает его функцию treadfunct, которая тут же пытается синхронизироваться с основным потоком. Во время паузы между вызовом таймера ей это удается и пока она выполняется, перерисовка останавливается, нетрудно увидеть, что просто метод TempProc зациклен, потому пока он будет выполняться, основной поток будет залочен, все что в нем (в TempProc) будет безопасно работать с VCL. Это получается абсолютный аналог Sincronize; - свойства класса TThread. Хочу заметить что объект класса TThread не создается (да и не может быть создан, ведь он абстрактный). -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||
|
|||||
Sunvas |
|
|||
![]() Соль и сахар ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3388 Регистрация: 12.3.2006 Где: Тосно Репутация: 28 Всего: 89 |
Большое спасибо!
alexeis1, давно бы так. А то танцевали с бубеном вокруг горшка... ЗЫ. Думаю тема весьма полезная - ее стоит почистить, закрыть и оставить следующим поколениям на обозрение. -------------------- Воспитывая детей по своему образу и подобию, родители почему-то надеются, что они будут лучше их. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |