|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Работаю над учебником "Многопоточное программирование в Delphi для начинающих". Учебник вместе с примерами доступен по ссылке: https://github.com/loginov-dmitry/multithread Примеры должны компилироваться во всех версиях Delphi, начиная с Delphi 2007 (кроме примера Ex12, где рассматривается метод Queue). В настоящее время в учебнике 58 страниц. Описаны минимальные базовые вещи, которые позволят начинающему разобраться с многопоточностью и начать разработку реальных проектов. Прошу отнестись к данной работе критически, т.к. есть желание (цель) давать ссылки на данный учебник при возникновении вопросов по многопоточности. Я потратил на эту работу в сумме около месяца и будет обидно читать комментарии типа "на второй странице пропущена запятая, значит всё там неправильно и читать дальше не буду". К сожалению, я успел описать далеко не всё, что хотелось бы. Надеюсь, что мне удастся и дальше продолжить эту работу (не в ущерб основной работе). В настоящее время оглавление следующее: Оглавление1. Вступление 1.1 Для чего используется многопоточное программирование в Delphi 1.2 В чём сложность разработки многопоточных программ в Delphi по сравнению с другими современными языками программирования 1.3 Поддержка многопоточности в операционных системах и процессорах 2. Базовый класс многопоточности - TThread 3. Предотвращаем зависание основного потока (имитация задачи длительного вычисления) 4. Управление временем жизни потоков 4.1 Использование свойства TThread.Terminated для выхода из метода Execute 4.2 Главная форма отвечает за прекращение работы потока и уничтожение объекта потока 4.3 Главная форма отвечает за уничтожение объекта потока с разовой задачей 17стр. 4.4 Главная форма отвечает за уничтожение нескольких долгоживущих потоков 19 4.5 Использование списка TObjectList для хранения ссылок на объекты потоков 23 4.6 Простой пример организации паузы в работе потока 26 4.7 Использование свойства FreeOnTerminate для автоматического уничтожения объекта потока при завершении работы потока 27 4.8 Организация корректного завершения работы программы при использовании свойства FreeOnTerminate 28 5. Передача информации из дополнительного потока в основной 32 5.1 Обращение к визуальным компонентам формы из дополнительного потока – как нельзя делать 32 5.2 Использование метода TThread.Synchronize для передачи данных в основной поток 32 5.3 Периодическое чтение основным потоком данных, подготовленных в дополнительном потоке 36 5.4 Использование функции SendMessage для передачи данных в основной поток 40 5.5 Использование функции PostMessage для передачи очереди сообщений в основной поток 44 5.6 Использование списка TThreadList для передачи очереди данных в основной поток 46 5.7 Использование метода TThread.Synchronize для передачи данных в основной поток – вариант с использованием анонимной процедуры 50 5.8 Использование метода TThread.Queue для передачи данных в основной поток 51 6. Где можно и где нельзя создавать и уничтожать потоки 57 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 12:09 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
DmSer, привет, начал читать. Что касается "запятых" ("а второй странице пропущена запятая...") то по-моему как раз язык нормальный, мысли пока что, сколько прочитал, были по-моему выражены ясно. ) Дочитал до начала описания класса TThread. Мне показалось, что есть "дырка" в изложении - переход от общего описания многопоточности в ОС к классу TThread. Может быть стоит написать про функцию CreateThread, при помощи которой можно создать поток в вызывающем её процессе (более строго, по документации: "который выполняется в адресном пространстве вызывающего процесса") и которую TThread инкапсулирует? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 13:24 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
s62 DmSer, привет, начал читать. Что касается "запятых" ("а второй странице пропущена запятая...") то по-моему как раз язык нормальный, мысли пока что, сколько прочитал, были по-моему выражены ясно. ) Дочитал до начала описания класса TThread. Мне показалось, что есть "дырка" в изложении - переход от общего описания многопоточности в ОС к классу TThread. Может быть стоит написать про функцию CreateThread, при помощи которой можно создать поток в вызывающем её процессе (более строго, по документации: "который выполняется в адресном пространстве вызывающего процесса") и которую TThread инкапсулирует? Спасибо за предложение! Но мне кажется, это будет лишняя информация для начинающих. Очень сложно разобраться, какой материал нужно включать, какой не нужно. Тонкостей различных миллион! Если описывать про CreateThread, а это чисто виндовая функция, тогда придётся описывать аналоги и в других ОС (Linux, MacOS, Android). Вероятно, можно будет обойтись более общей формулировкой о том, что доп. поток на самом деле создаёт ОС, а класс TThread является обёрткой... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 14:03 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
DmSerЕсли описывать про CreateThread, а это чисто виндовая функция Причём такая, которой не надо пользоваться практически никогда. _beginthreadex() описать таки надо. Хотя бы пробы было понимание, что "TThread это не поток". Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 14:17 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
DmSer Вероятно, можно будет обойтись более общей формулировкой о том, что доп. поток на самом деле создаёт ОС, а класс TThread является обёрткой... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 15:41 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
DmSer Работаю над учебником "Многопоточное программирование в Delphi для начинающих". так вот почему такой странный топик про потоки. А я-то воспринял, как будто новичок украл твой ник и забавляется. Извини за наезд :) Исходник книги на чем пишешь? Я тут кое-что время от времени перевожу, из markdown экспортируется весьма читабельно, а у тебя бледненько - текст труднее воспринимается ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 16:24 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
DmSer> Работаю над учебником "Многопоточное программирование в Delphi для начинающих". Это дело хорошее, полезное. Научный редактор есть или ты надеешься на краудсорсинговую вычитку? > Примеры должны компилироваться во всех версиях Delphi, начиная > с Delphi 2007 (кроме примера Ex12, где рассматривается метод Queue). В Д7 не проверялось? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 16:56 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Чтобы разрабатывать реальные проекты надо не многопоточность изучать, а терминологию и практики... Очень хороший пример всего этого описан в ответе здесь . Далее.. Delphi сейчас - это кроссплатформенная среда разработки, следовательно все примеры должны быть кроссплатформенные. Все что в современной версии досталось в наследство от 1-7 версий должно быть похоронено как deprecated. У этого всего давно появились другие аналоги, более удобные в проектировании и разработке. Как минимум уже в начале неверно описана область применения PPL. PPL - это способ выполнить некую работу (не важно какую, абсолютно любую) конкурентно не вдаваясь в детали реализации. Как она будет выполнена: параллельно, асинхронно или синхронно - это дело десятое и в современно мире особо об этом задумываться ненужно. Когда над проектом работают десятки разработчиков, порог входа должен быть низкий, чтобы иметь возможность дешево менять ресурсы, для этого и придумывают различные библиотеки и абстракции, которые в освоении намного проще. Проблема в Дельфи в том, что разработчики которые туда пытаются придти учатся по книжкам которые написаны были во времена высокого порога входа в программирование, а не когда курсы клепают по 100 "программистов" в день... Поэтому лучше, чтобы появлялись книжки, которые позволят вчерашним студентам, которые не знают как там работает под капотом, да и не надо им знать, но которые будут эффективно решать реальные бизнес-задачи используя современные инструменты. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 17:04 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
авторЯ хотел бы выделить две основные причины использования многопоточности в Delphi-программах Задачи длительного ожидания завершения ввода-вывода. Вы путаете теплое с мягким. Такие задачи должны выполняться асинхронно.. Другой поток - это способ реализации, при чем довольно не эффективный, если таких запросов много. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 17:24 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Первый пример показан через оверхед. Намного лаконичнее решается через Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9.
И кстати, такая вариация намного удачнее, чем через отдельный класс, потому что явно видно в каком месте какую работу необходимо выполнить в потоке отличном от вызываемого. А еще лучше так никогда не делать и не показывать что вообще можно... Потому что Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9.
намного лучше, т.к. нет оверхеда на создание/разрушение потоков Лучше учить решать задачи наиболее подходящим инструментом, чем учить использовать примитив везде где попало. Иначе книжку надо переименовать в Работа с классом TThread, а не многопоточное программирование... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:15 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite лучше, чтобы появлялись книжки, которые позволят вчерашним студентам, которые не знают как там работает под капотом, да и не надо им знать, но которые будут эффективно решать реальные бизнес-задачи используя современные инструменты. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:23 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite Код: pascal 1.
Что будет, если DoLongCalculations будет выполняться часами, а пользователь захочет закрыть программу? Нежданчик? И таким "современным" методам вы предлагаете учить молодежь? Чтобы они и не знали, как сделать по-нормальному, чтобы контролировать всё? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:29 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
YuRock, Почти все проблемы для известных и популярных библиотек уже описаны и описаны способы решения. В том числе например и для PPL. Проще обучить как решать задачи для которых PPL предпочтительнее, чем решать эти же задачи на TThread ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:30 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite YuRock, Почти все проблемы для известных и популярных библиотек уже описаны и описаны способы решения. В том числе например и для PPL. Проще обучить как решать задачи для которых PPL предпочтительнее, чем решать эти же задачи на TThread Какие нафиг библиотеки, я не про них говорю, а про реальные проекты, которые будут делать программисты. Научить TTask'у, конечно, проще, чем TThread'у, только толку от этого ученика не будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:34 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
YuRock X-Cite Код: pascal 1.
Что будет, если DoLongCalculations будет выполняться часами, а пользователь захочет закрыть программу? Нежданчик? жданчик будет. Ошибки, зависания, прочие прелести. Я от TTask отказался как раз из-за абсолютно фантастических вещей при его остановке. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 18:39 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
YuRock Что будет, если DoLongCalculations будет выполняться часами, а пользователь захочет закрыть программу? Тоже самое что и в TThread.Execute(), но в отличие от TThread бизнес-единица алгоритма будет всегда в согласованном состоянии. Примеры: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
Что будет? Access Violation будет. Отстрелили ногу. TTask.Run - корректно дождется конца. т.е. в TThread как минимум надо самостоятельно ждать окончания работы, чтобы корректно продолжить. Что надо сделать чтобы не ждать конца? А закончить работу пораньше. Одно и тоже, что в TTask что в TThread - только способы реализации будут разные. Только с CreateAnonymousThread - все намного сложнее, окей, применяем старый подход через отдельный класс Реализация для TThread Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.
Реализация для TTask Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
И что мы видим... Работает и то и то. Но преимущества TTask 1) Код не размазан и лаконичен 2) Нет оверхеда на создание/уничтожение потоков 3) Задачу выполнения работы решает не примитив (поток), а инструмент (задача) который по факту может ее решить как угодно, вплоть до делегирования другому процессу. Вы как поставите задачу подчиненному программисту? 1) Произвести запись в файл асинхронно. 2) Произвести запись в файл используя отдельный поток. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 19:54 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite Что будет? Access Violation будет. С чего бы? GUI-поток завершится, но это не беда. Процесс будет жить, пока другой поток (другие потоки) не закончит свою работу. Вторичному потоку, который пишет в файл, от бывшего главного вроде бы ничего не нужно. Допишет файл, и тихо выйдет. По идее. На практике не проверил. Единственно, что вызывает сомнения - не будет ли сломан менеджер памяти, который должен на выходе из процедуры освободить байтовый массив. На первый взгляд, не будет. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 20:42 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Док так вот почему такой странный топик про потоки. А я-то воспринял, как будто новичок украл твой ник и забавляется. Извини за наезд :) Все нормально! У меня в тот момент возникли сложности с тем, как лучше описать Queue. Не получалось её описать в позитивном ключе. А тему завел по причине того, что у некоторых разработчиков на этом форуме есть положительный опыт и позитивные отзывы. В результате та тема мне очень помогла, удалось очень подробно описать Queue в позитивном ключе. А кое-кто писал, что на оф. сайте по Queue всё есть, головой только немного подумать нужно. Ну да, я подумал, разобрался (вроде), но страшно представить, сколько времени уйдет у новичка, если он будет методом тыка все грабли перебирать. Док Исходник книги на чем пишешь? Я тут кое-что время от времени перевожу, из markdown экспортируется весьма читабельно, а у тебя бледненько - текст труднее воспринимается Пишу в ворде 2010года. Про markdown не знал, спасибо. Почитаю, пока отпуск! В идеале хотелось бы пользоваться специализированным решением, которое было бы совместимо с системой контроля версий. Но при этом не тратить много времени. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 22:31 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Гаджимурадов Рустам DmSer> Работаю над учебником "Многопоточное программирование в Delphi для начинающих". Это дело хорошее, полезное. Научный редактор есть или ты надеешься на краудсорсинговую вычитку? Я надеюсь, что если там есть откровенная лажа, то она без внимания не останется :) При этом понимаю, что читать 58 страниц такого текста - это не роман прочитать. За час не управишься! :) Гаджимурадов Рустам > Примеры должны компилироваться во всех версиях Delphi, начиная > с Delphi 2007 (кроме примера Ex12, где рассматривается метод Queue). В Д7 не проверялось? Я использую модуль TimeIntervals, там есть класс TTimeInterval, который является рекордом с методами. В D7 такое не скомпилится. Также я предполагаю, что в D7 были бы проблемы с отображением исходников в кодировке UTF-8. А мне приходится использовать UTF-8 для корректного отображения в гитхабе. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 22:40 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite Чтобы разрабатывать реальные проекты надо не многопоточность изучать, а терминологию и практики... Очень хороший пример всего этого описан в ответе здесь . Далее.. Delphi сейчас - это кроссплатформенная среда разработки, следовательно все примеры должны быть кроссплатформенные. Все что в современной версии досталось в наследство от 1-7 версий должно быть похоронено как deprecated. У этого всего давно появились другие аналоги, более удобные в проектировании и разработке. Как минимум уже в начале неверно описана область применения PPL. PPL - это способ выполнить некую работу (не важно какую, абсолютно любую) конкурентно не вдаваясь в детали реализации. Как она будет выполнена: параллельно, асинхронно или синхронно - это дело десятое и в современно мире особо об этом задумываться ненужно. Когда над проектом работают десятки разработчиков, порог входа должен быть низкий, чтобы иметь возможность дешево менять ресурсы, для этого и придумывают различные библиотеки и абстракции, которые в освоении намного проще. Проблема в Дельфи в том, что разработчики которые туда пытаются придти учатся по книжкам которые написаны были во времена высокого порога входа в программирование, а не когда курсы клепают по 100 "программистов" в день... Поэтому лучше, чтобы появлялись книжки, которые позволят вчерашним студентам, которые не знают как там работает под капотом, да и не надо им знать, но которые будут эффективно решать реальные бизнес-задачи используя современные инструменты. Я достаточно много думал о том, нужно ли описывать базовые вещи, или сразу начать с PPL. Моя уверенность в том, что важнее описать базовые вещи укрепилась после серии вопросов на этом форуме, которые относятся к PPL, а также к CreateAnonymousThread от начинающих программистов и не очень. Да, начинающего программиста можно, как мартышку, научить выполнять конкретное действие через TTask.Run. Но он нихрена не понимает, как это работает, если не знает базовые вещи. Проблема в Дельфи в том, что там нет того асинхронного программирования, которое есть в C#, JavaScript, Rust, Kotlin и некоторых других ЯП. В ЯП, где есть асинхронная конструкция async/await (либо аналоги), программисты решают реальные бизнес-задачи и как раз там им не требуется задумываться о том, как задача будет выполнена: параллельно, асинхронно или синхронно. В языках, которые изначально спроектированы как многопоточные (имею ввиду прежде всего GoLang) в сто раз меньше связанных с многопоточностью проблем и граблей, чем в языке Delphi. А теперь им еще и шедулер улучшили! ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 22:58 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite авторЯ хотел бы выделить две основные причины использования многопоточности в Delphi-программах Задачи длительного ожидания завершения ввода-вывода. Вы путаете теплое с мягким. Такие задачи должны выполняться асинхронно.. Другой поток - это способ реализации, при чем довольно не эффективный, если таких запросов много. Да, должны! Но какого объёма книжку нужно написать для начинающего, чтобы он смог написать красивую, надёжную, быструю программу с использованием, скажем Overbyte ICS? А будет ли он читать такую книгу? А что ему даст асинхронность Overbyte ICS (какое преимущество), если ему потребовалось запрос к БД выполнить? А будет ли он читать такую книгу, если тут на форуме все примеры в основном на Indy? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 23:04 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite Потому что Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9.
намного лучше, т.к. нет оверхеда на создание/разрушение потоков Лучше учить решать задачи наиболее подходящим инструментом, чем учить использовать примитив везде где попало. Иначе книжку надо переименовать в Работа с классом TThread, а не многопоточное программирование... В интернете достаточно хороших примеров того, как использовать PPL. Мне и добавить к ним нечего. Пусть начинающие учатся по этим примерам, ради Бога! Если удастся работать эффективно, я буду только рад за них. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 23:09 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
Хорошо работающая PPL это благо для начинающих (и не только). Либо заголовок не правильный, либо план учебника ... ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 23:26 |
|
Многопоточное программирование в Delphi для начинающих
|
|||
---|---|---|---|
#18+
X-Cite Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
. И тут блестящая PPL разом превратилась в тыкву! Оказывается, как и с TThread, нужно останавливать таски перед завершением программы, а в таске проверять необходимость завершения :) ... |
|||
:
Нравится:
Не нравится:
|
|||
08.07.2020, 23:27 |
|
|
start [/forum/topic.php?fid=58&msg=39977636&tid=2036872]: |
0ms |
get settings: |
16ms |
get forum list: |
5ms |
check forum access: |
1ms |
check topic access: |
1ms |
track hit: |
36ms |
get topic data: |
3ms |
get forum data: |
1ms |
get page messages: |
459ms |
get tp. blocked users: |
0ms |
others: | 2549ms |
total: | 3071ms |
0 / 0 |