Threading в Python 3: работа с потоками — Запуск и остановк и работа с очередями

Можно ли считать threading многопоточным? Современное программное обеспечение проектируется так, что его функции и задачи могут выполняться параллельно. Python предоставляет программисту мощный набор инструментов для работы с потоками в библиотеке threading. Многопоточность — это выполнение программы сразу в нескольких потоках, которые выполняют её функции одновременно. Многопоточное программирование можно спутать с мультипроцессорным. На самом деле их концепции очень похожи, но если в первом случае программа работает с потоками, то в другом — с процессами. Разница между потоками и процессами проста: потоки имеют общую память, поэтому изменения в одном потоке видны в других, а процессы используют разные области памяти. На самом деле, если рассмотреть одноядерный процессор, операции из разных потоков не выполняются параллельно. Одно ядро может выполнить только одну операцию в единицу времени, но так как операции выполняются очень быстро, создается ощущение параллельного выполнения, псевдопараллельность. По-настоящему параллельно программы могут работать только на многоядерных процессорах, где каждое ядро может выполнять операции независимо от других. Отличным примером использования многопоточности является программа, где отрисовка графического интерфейса и обработка ввода пользователя управляются разными потоками.

Если бы обе задачи были помещены в один поток, отрисовка интерфейса прерывалась бы каждый раз, когда программа получает ввод от пользователя. Использование двух потоков позволяет сделать выполнение этих функций независимым друг от друга. Однако при выполнении многопоточной программы на одноядерном процессоре, её производительность будет ниже, чем если бы она была написана в один поток. Это происходит потому, что на реализацию и управление потоками тратится дополнительная память. Можно ли считать threading многопоточным? В Python используется GIL (Global Interpreter Lock), который однопоточный. Все потоки, которые создаются с помощью threading будут работать внутри потока GIL. В связи с этим они будут обрабатываться только одним ядром. Ни о какой работе одновременно на нескольких физических ядрах процессора не может быть и речи. А так как threading будет выполняться только на одном ядре процессора, то нету преимущества по скорости, только наоборот — threading замедлит работу. Обрабатывать нажатие кнопки в графическом интерфейсе, например с помощью Tkinter. Если по нажатию кнопки надо производить много действий, которые требуют времени, то эти действия надо выполнять в другом потоке, чтобы графический интерфейс не подвис на это время.

Соответственно кнопки надо блокировать, а как поток завершит вычисления — обратно разблокировать. Если наша программа работает одновременно с несколькими подключенными устройствами. Они могут быть подключены к разным COM-портам. Если мы загружаем файлы из сети и одновременно обрабатываем уже загруженные. Если нам нужно, чтобы наша программа работала на нескольких физических ядрах процессора одновременно, то следует обратить внимание на другой модуль — Multiprocessing. В чём преимущества тогда модуля Threading по сравнению с Multiprocessing? Проще передавать данные из потока в основную программу. Вообще можно даже использовать глобальные переменные. Но при этом надо правильно проектировать программу, чтобы не было ошибок, связанных с «Состоянием гонки», которые мы рассмотрим ниже. Таким образом, если наша программа будет запускаться на одноядерном компьютере или нагрузка на процессор будет не большой, то Threading — оптимальный выбор. Threading — это стандартный модуль, который поставляется вместе с интерпретатором. Работать с потоками можно, создавая экземпляры класса Thread. Чтобы создать отдельный, поток нужно создать экземпляр класса и применить к нему метод start().

Здесь мы функцию mydef запустили в отдельном потоке. Эта конструкция позволяет создать новый поток, создав экземпляр класса Thread. Имеет значение None, зарезервирована для будущего расширения при реализации класса ThreadGroup. Это функция, которая выполняется в потоке с помощью метода run(), если передано значение None, ничего не вызывается. Это имя потока, по умолчанию оно принимает значение «Thread-X», где X — десятичное число. Программист может задать имя вручную. Это кортеж, в котором хранятся аргументы, передаваемые в вызываемую функцию. Это словарь, в котором хранятся аргументы, передаваемые в функцию. Это параметр, который устанавливает, является ли поток демоническим. По умолчанию имеет значение None, тогда свойство daemonic наследуется от текущего потока. Программист может самостоятельно установить значение параметра. Демонами называют процессы, которые работают в фоновом режиме. В Python для демона есть более конкретное значение: демонический поток или поток демона. В отличие от обычных потоков поток демона автоматически завершает свою работу при закрытии программы. Иными словами, программа не будет ожидать завершения демонического потока, при её закрытии эти потоки уничтожаются, в каком бы состоянии они не находились.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *