Итак, параллельная программа , разработанная с использованием OpenMP , представляется в виде набора последовательных ( однопотоковых ) и параллельных ( многопотоковых ) фрагментов программного кода (см. рис. 7.2).
7.2.1. Директива parallel для определения параллельных фрагментов
Для выделения параллельных фрагментов программы следует использовать директиву parallel :
#pragma omp parallel [ . ]
Для блока (как и для блоков всех других директив OpenMP ) должно выполняться правило «один вход — один выход», т.е. передача управления извне в блок и из блока за пределы блока не допускается.
Директива parallel является одной из основных директив OpenMP . Правила, определяющие действия директивы, состоят в следующем:
- Когда программа достигает директиву parallel , создается набор ( team ) из N потоков; исходный поток программы является основным потоком этого набора ( master thread ) и имеет номер 0.
- Программный код блока, следующий за директивой, дублируется или может быть разделен при помощи директив между потоками для параллельного выполнения.
- В конце программного блока директивы обеспечивается синхронизация потоков — выполняется ожидание окончания вычислений всех потоков; далее все потоки завершаются — дальнейшие вычисления продолжает выполнять только основной поток (в зависимости от среды реализации OpenMP потоки могут не завершаться, а приостанавливаться до начала следующего параллельного фрагмента — такой подход позволяет снизить затраты на создание и удаление потоков).
7.2.2. Пример первой параллельной программы
Подчеркнем чрезвычайно важный момент — оказывается, даже такого краткого рассмотрения возможностей технологии OpenMP достаточно для разработки пусть и простых, но параллельных программ. Приведем практически стандартную первую программу, разрабатываемую при освоению новых языков программирования — программу, осуществляющую вывод приветственного сообщения «Hello World !» Итак:
Убей В СЕБЕ ЗВЕРЯ чтобы ВЫЖИТЬ! Игры Габара ! ЧЕЛЛЕНДЖ на ЧЕЛОВЕЧНОСТЬ!
#include main () < /* Выделение параллельного фрагмента*/ #pragma omp parallel < printf(«Hello World !n»); >/* Завершение параллельного фрагмента */ >
7.1. Первая параллельная программа на OpenMP
В приведенной программе файл omp.h содержит определения именованных констант , прототипов функций и типов данных OpenMP — подключение этого файла является обязательным, если в программе используются функции OpenMP . При выполнении программы по директиве parallel будут созданы потоки (по умолчанию их количество совпадает с числом имеющихся вычислительных элементов системы — процессоров или ядер), каждый поток выполнит программный блок, следуемый за директивой, и, как результат, программа выведет сообщение «Hello World !» столько раз, сколько будет иметься потоков.
7.2.3. Основные понятия параллельной программы: фрагмент, область, секция
После рассмотрения примера важно отметить также, что параллельное выполнение программы будет осуществляться не только для программного блока, непосредственно следующего за директивой parallel , но и для всех функций, вызываемых из этого блока (см. рис. 7.3). Для обозначения этих динамически-возникающих параллельно выполняемых участков программного кода в OpenMP используется понятие параллельных областей ( parallel region ) — ранее, в предшествующих версиях стандарта использовался термин динамический контекст ( dynamic extent ).
Кто последний покинет стол? ИГРЫ ГАБАРА! Девушки 4 сезон!
Рис. 7.3. Область видимости директив OpenMP
Ряд директив OpenMP допускает использование как непосредственно в блоках директивы, так и в параллельных областях. Такие директивы носят наименование отделяемых директив ( orphaned directives ).
Для более точного понимания излагаемого учебного материала сведем воедино введенные термины и понятия (в скобках даются названия, используемые в стандарте 2.5):
- Параллельный фрагмент ( parallel construct ) — блок программы, управляемый директивой parallel ; именно параллельные фрагменты, совместно с параллельными областями, представляют параллельно-выполняемую часть программы; в предшествующих стандартах для обозначения данного понятия использовался термин лексический контекст ( lexical extent ) директивы parallel .
- Параллельная область ( parallel region ) — параллельно выполняемые участки программного кода, динамически-возникающие в результате вызова функций из параллельных фрагментов — см. рис. 7.3.
- Параллельная секция ( parallel section ) — часть параллельного фрагмента, выделяемая для параллельного выполнения при помощи директивы section — см. подраздел 7.6.
7.2.4. Параметры директивы parallel
Приведем перечень параметров директивы parallel :
- if (scalar_expression)
- private (list)
- shared (list)
- default (shared | none)
- firstprivate (list)
- reduction (operator: list)
- copyin (list)
- num_threads (scalar_expression)
Список параметров приведен только для справки, пояснения по использованию этих параметров будут даны позднее по мере изложения учебного материала.
7.2.5. Определение времени выполнения параллельной программы
Практически сразу после разработки первой параллельной программы появляется необходимость определения времени выполнения вычислений, поскольку в большинстве случаев основной целью использования параллельных вычислительных систем является сокращений времени выполняемых расчетов. Используемые обычно средства для измерения времени работы программ зависят, как правило, от аппаратной платформы, операционной системы, алгоритмического языка и т.п. Стандарт OpenMP включает определение специальных функций для измерения времени, использование которых позволяет устранить зависимость от среды выполнения параллельных программ.
Получение текущего момента времени выполнения программы обеспечивается при помощи функции:
double omp_get_wtime(void),
результат вызова которой есть количество секунд, прошедших от некоторого определенного момента времени в прошлом. Этот момент времени в прошлом, от которого происходит отсчет секунд, может зависеть от среды реализации OpenMP и, тем самым, для ухода от такой зависимости функцию omp_get_wtime следует использовать только для определения длительности выполнения тех или иных фрагментов кода параллельных программ. Возможная схема применения функции omp_get_wtime может состоять в следующем:
double t1, t2, dt; t1 = omp_get_wtime (); … t2 = omp_get_wtime (); dt = t2 — t1;
Точность измерения времени также может зависеть от среды выполнения параллельной программы. Для определения текущего значения точности может быть использована функция:
double omp_get_wtick(void),
позволяющая определить время в секундах между двумя последовательными показателями времени аппаратного таймера используемой компьютерной системы.
7.3. Распределение вычислительной нагрузки между потоками (распараллеливание по данным для циклов)
Как уже отмечалось ранее, программный код блока директивы parallel по умолчанию исполняется всеми потоками. Данный способ может быть полезен, когда нужно выполнить одни и те же действия многократно (как в примере 7.1) или когда один и тот же программный код может быть применен для выполнения обработки разных данных. Последний вариант достаточно широко используется при разработке параллельных алгоритмов и программ и обычно именуется распараллеливанием по данным. В рамках данного подхода в OpenMP наряду с обычным повторением в потоках одного и того же программного кода — как в директиве parallel — можно осуществить разделение итеративно-выполняемых действий в циклах для непосредственного указания, над какими данными должными выполняться соответствующие вычисления. Такая возможность является тем более важной, поскольку во многих случаях именно в циклах выполняется основная часть вычислительно-трудоемких вычислений.
Для распараллеливания циклов в OpenMP применяется директива for :
#pragma omp for [ . ]
После этой директивы итерации цикла распределяются между потоками и, как результат, могут быть выполнены параллельно (см. рис. 7.4) — понятно, что такое распараллеливание возможно только, если между итерациями цикла нет информационной зависимости.
Рис. 7.4. Общая схема распараллеливания циклов
Важно отметить, что для распараллеливания цикл for должен иметь некоторый «канонический» тип цикла со счетчиком 2 Смысл требования «каноничности» состоит в том, чтобы на момент начала выполнения цикла существовала возможность определения числа итераций цикла :
for (index = first; index < end; increment_expr)
Здесь index должен быть целой переменной; на месте знака » цикла может находиться любая операция сравнения » » или » >= «. Операция изменения переменной цикла должна иметь одну из следующих форм:
- index++ , ++index ,
- index— , —index ,
- index+=incr , index-=incr ,
- index=index+incr , index=incr+index ,
- index=index-incr
И, конечно же, переменные, используемые в заголовке оператора цикла , не должны изменяться в теле цикла .
В качестве примера использования директивы рассмотрим учебную задачу вычисления суммы элементов для каждой строки прямоугольной матрицы:
#include #define CHUNK 100 #define NMAX 1000 main () < int i, j, sum; float a[NMAX][NMAX]; #pragma omp parallel shared(a) private(i,j,sum) < #pragma omp for for (i=0; i < NMAX; i++) < sum = 0; for (j=0; j < NMAX; j++) sum += a[i][j]; printf («Сумма элементов строки %d равна %fn»,i,sum); >/* Завершение параллельного фрагмента */ >
7.2. Пример распараллеливания цикла
В приведенной программе для директивы parallel появились два параметра — их назначение будет описано в следующем подразделе, здесь же отметим, что параметры директивы shared и private определяют доступность данных в потоках программы — переменные, описанные как shared , являются общими для потоков; для переменных с описанием private создаются отдельные копии для каждого потока, эти локальные копии могут использоваться в потоках независимо друг от друга.
Следует отметить, что если в блоке директивы parallel нет ничего, кроме директивы for , то обе директивы можно объединить в одну, т.е. пример 7.2 может быть переписан в виде:
#include #define NMAX 1000 main () < int i, j, sum; float a[NMAX][NMAX]; #pragma omp parallel for shared(a) private(i,j,sum) < for (i=0; i < NMAX; i++) < sum = 0; for (j=0; j < NMAX; j++) sum += a[i][j]; printf («Сумма элементов строки %d равна %fn»,i,sum); >/* Завершение параллельного фрагмента */ >
7.3. Пример использования объединенной директивы parallel for
Параметрами директивы for являются:
- schedule (type [, chunk ])
- ordered
- nowait
- private (list)
- shared (list)
- firstprivate (list)
- lastprivate (list)
- reduction (operator: list)
Последние пять параметров директивы будут рассмотрены в следующем подразделе, здесь же приведем описание оставшихся параметров.
Источник: intuit.ru
Как автоматизировать задачи в Windows 10, чтобы сэкономить время
В мире интеллектуальных технологий мы упускаем кучу вещей, если не делаем автоматизацию правильно. В Android есть приложение Tasker для автоматизации, которое теперь получает новую функцию «Правила».
В iOS уже есть мощное приложение «Горячие клавиши» для автоматизации множества задач и многого другого. Но это смартфоны, а ПК? Что ж, в Windows 10 есть похожий инструмент под названием Task Scheduler, который позволяет вам выполнять множество задач в зависимости от времени, событий и различных других условий.
Итак, в этой статье мы представим вам подробное руководство по автоматизации задач в Windows 10. Наряду с этим мы также поделились базовым руководством по PowerShell в следующем разделе.
Автоматизация в Windows 10
Прежде чем двигаться вперед, позвольте мне кратко объяснить некоторые основные моменты этой статьи. Для автоматизации задач в Windows 10, Есть два основных метода, первый — это встроенный инструмент под названием Task Scheduler, который довольно прост и понятен. И следующий метод — это автоматизация с помощью PowerShell, которая немного сложна, но также многофункциональна.
Программы для Windows, мобильные приложения, игры — ВСЁ БЕСПЛАТНО, в нашем закрытом телеграмм канале — Подписывайтесь:)
1. Автоматизация задач в Windows 10 с помощью планировщика задач
Лучший способ чему-то научиться — это решать проблемы. Итак, здесь мы будем реализовать основную задачу. Например, скажем, каждый раз, когда мы включаем наш компьютер, он открывает браузер, а затем направляется на несколько интересных сайтов. Поэтому все, что нам нужно сделать, — это автоматизировать эту рутинную задачу, чтобы мы могли сэкономить время и количество кликов. Давайте начнем.
1. Нажмите клавишу Windows один раз и введите «Планировщик заданий», Откройте первый результат и закрепите его на панели задач, потому что он вам понадобится постоянно.
2. Поначалу интерфейс может показаться немного сложным, но просто следуйте моим инструкциям, и вы справитесь. Теперь, нажмите «Создать задачу» на правой панели.
3. После этого укажите название вашей задачи и установите флажок «Запускать с наивысшими привилегиями», Он не будет запрашивать UAC или запрашивать разрешение администратора перед запуском задачи.
4. Сейчас перейдите на вкладку «Триггеры» выше и нажмите на кнопку «Создать».
5. Здесь выберите опцию «При входе в систему» в раскрывающемся меню и нажмите кнопку «ОК». Вы также можете отложить задачу на несколько секунд, но давайте просто пока оставим ее. Как примечание, я всегда откладываю свои связанные с интернетом задачи на 30 секунд, чтобы компьютер мог подключиться к WiFi и быть готовым вовремя.
6. Теперь перейдите на вкладку «Действия» и нажмите кнопку «Создать». Вот, выберите «Начать программу» из раскрывающегося меню, мы будем открывать Google Chrome.
7. Затем нажмите кнопку «Обзор» и выберите Chrome с рабочего стола или любого места.
8. После этого введите ваш URL сайта в поле «Добавить аргумент», Например, вы можете напечатать okdk.ru и нажмите кнопку «ОК». В случае, если вы хотите открыть несколько сайтов сразу же просто вставьте пробел между ними и зайдите на другой сайт.
okdk.ru google.com
- Вы также можете добавить свой плейлист Spotify или что угодно. Просто сделайте пробел между сайтами. Chrome автоматически откроет эти веб-сайты, как только вы войдете в систему. Обратите внимание, что Вы можете просто написать доменное имя или предоставить целое HTTPS ссылка, Все работает!
okdk.ru google.com https://open.spotify.com/playlist/37i9dQZF1DX2Ja6eBQeGaS
9. Сделав это, перейдите на вкладку «Условия» и снимите обе опции в разделе «Мощность», Это позволит ПК выполнять задачу независимо от состояния батареи или зарядки.
10. Наконец, перейдите на вкладку «Настройки». Здесь нам не нужно ничего трогать, но убедитесь, что установлен флажок «Разрешить выполнение задачи по требованию», кроме того, просмотрите другие варианты, чтобы вы могли понять, что вы можете сделать с помощью планировщика задач. Теперь нажмите на кнопку «ОК».
11. Вы успешно создали задачу, чтобы открыть ваши любимые веб-сайты после включения компьютера. Вы можете найдите свою задачу в «Библиотеке планировщика задач» на левой панели. Если задача не отображается, нажмите кнопку «Обновить» на панели действий, расположенной справа.
12. Далее вы можете протестировать задачу вручную, работает ли правильно, нажав кнопку «Выполнить» на правой панели. Если все работает нормально, перезагрузите компьютер, и вы сможете автоматизировать серию задач в кратчайшие сроки. Наслаждайтесь!
Эта задача была для открытия сайтов в Chrome, но может быть несколько вариантов использования, основанных на вашей повседневной жизни. Например, вы можете выбрать автоматическое подключение к определенной точке Wi-Fi, создать задачу по очистке корзины через определенное количество дней, вы также можете запускать приложения Office или что угодно.
Единственные изменения должны быть сделаны на вкладке «Действие» и «Триггеры», но кроме этого все остается схожим. Кроме того, я бы посоветовал вам поработать с различными настройками, чтобы правильно понять планирование задач.
2. Автоматизация задач в Windows 10 с помощью PowerShell
В приведенном выше разделе мы узнали, как автоматизировать задачи с помощью планировщика задач. Но есть родной инструмент для создания сценариев в Windows 10 под названием PowerShell который довольно продвинут и универсален. Вы можете делать что-нибудь с помощью нескольких команд. Я знаю, что многие пользователи боятся видеть синий экран PowerShell, но, поверьте мне, это довольно легко. Позвольте мне просто сказать, что это не хардкорное программирование, так что не волнуйтесь.
Кроме того, есть некоторые ключевые различия между PowerShell и планировщиком задач. PowerShell — это не инструмент автоматизации, а инструмент создания сценариев. Он еще требует планировщика заданий для автоматизации своего сценария, принимая во внимание, что Планировщик заданий сам по себе является полным инструментом, где вы можете создавать сценарии, а также автоматизировать эти задачи.
Кроме того, с точки зрения производительности, Планировщик заданий довольно быстрый потому что он выполняет все из приложения. Однако сфера его применения относительно ограничена, поскольку вы не можете углубляться в другие программы и функции.
Так что, если у вас есть небольшая задача под рукой, то Task Scheduler отлично подходит. Тем не мение, PowerShell очень динамичен и может взаимодействовать со многими программами сразу, но это довольно медленно при выполнении этих команд.
Таким образом, с одной стороны, вы получаете более быстрое выполнение, но ограниченные возможности, а с другой стороны, вы получаете универсальную поддержку, но более медленное выполнение. Тем не менее, здесь мы пройдем тот же пример.
Начало работы с синтаксисом PowerShell
Позвольте мне начать с примера. Ниже вы видите команду PowerShell для открытия нескольких сайтов в Chrome. Вот, Запуск процесса это команда для запуска программы а также chrome.exe это исполняемое имя программы. Очень похоже на планировщик заданий, верно? Очень просто.
Start-Process "chrome.exe" "okdk.ru google.com"
Вы также можете добавить свой плейлист Spotify, любимые субреддиты или что угодно.
Start-Process «chrome.exe» «okdk.ru google.com https://www.reddit.com/r/Android https://open.spotify.com/playlist/37i9dQZF1DX2Ja6eBQeGaS»
Теперь, когда вы поняли синтаксис и что означают различные аргументы команды PowerShell, давайте начнем.
Шаги для создания скрипта PowerShell
1. Откройте файл блокнота и вставьте приведенную ниже команду.
Start-Process «chrome.exe» «okdk.ru google.com https://www.reddit.com/r/Android https://open.spotify.com/playlist/37i9dQZF1DX2Ja6eBQeGaS»
2. Вы можете изменить сайт в соответствии с вашими предпочтениями, И если вы хотите предоставить другой браузер, щелкните правой кнопкой мыши значок браузера и откройте «Свойства». В поле назначения скопируйте последнюю XXXX.exe часть и вставьте ее в файл блокнота. Таким образом, вы можете найти исполняемые имена и для других программ.
Примечание: Если это не работает, вы можете вставить весь адрес из целевого поля. Вот пример браузера Microsoft Edge. Вы можете сделать это для любой программы.
Start-Process "C:Program Files (x86)MicrosoftEdge BetaApplicationmsedge.exe" "okdk.ru google.com"
3. Теперь перейдите в «Файл» в Блокноте и нажмите «Сохранить как». Здесь дайте имя вашему сценарию, а затем Добавляйте .ps1 расширение в конце, PS1 является расширением сценариев PowerShell. Кроме того, не забудьте сохранить имя файла в одном слове.
4. Сделав это, откройте планировщик заданий и создайте новую задачу, выполнив шаги 1-5 упоминается в приведенном выше разделе. Перейдя на вкладку «Действие», выберите «Запустить программу» в раскрывающемся меню и введите powershell.exe в окне «Программа / скрипт».
5. Теперь щелкните правой кнопкой мыши файл PS1 и откройте «Свойства». Здесь вы найдете путь к файлу в разделе местоположения. Скопируйте и добавьте filename.ps1 в конце. Вот как это должно выглядеть. Нам понадобится этот адрес на следующем шаге.
C:UsersBeebomDesktopbrowser.ps1
6. Замените ниже адрес с вашим адресом из вышеприведенного шага и вставьте его в поле «Аргумент». После этого нажмите кнопку «ОК».
-windowstyle Hidden -file C:UsersBeebomDesktopbrowser.ps1
7. Наконец, вы закончили определение части Action с помощью скрипта PowerShell. В настоящее время, выполните те же шаги с 9 до 12 из раздела планировщика заданий. Вы можете протестировать скрипт, нажав кнопку «Выполнить». Как я объяснил выше, окно PowerShell может вызвать маленькое всплывающее окно, потому что выполнение сценария немного медленное.
Вот как вы можете создать простой сценарий в PowerShell и автоматизировать его с помощью планировщика задач. То, что я показал выше, является лишь верхушкой айсберга. Вы можете сделать намного больше, и возможности безграничны. Например, Вы можете добавить команды для запуска отдельной программы, удалить старые файлы из определенных папок, отключить обновление Windows 10 и другие службы уровня ОС, включить службы поддержки и многое другое, используя тот же файл PS1.
Вам больше не нужно возвращаться к планировщику заданий, чтобы что-то настроить, просто внесите изменения в файл PS1 с помощью блокнота, и он запустит все изменения. Круто, верно? В ближайшие дни мы поделимся некоторыми классными скриптами PowerShell для автоматизации задач в Windows 10, так что следите за обновлениями.
Сценарии Ace PowerShell и автоматизация рутинных задач в Windows 10
Это было наше подробное руководство о том, как начать автоматизацию в Windows 10. Существует множество скрытых инструментов, которыми мы можем воспользоваться, и планировщик задач является одним из них.
Источник: okdk.ru
Асинхронное приложение ч.1 / tkinter 15
Базовый метод предотвращения блокировки основного потока в Tkinter — это планирование действий, которые будут выполнены после истечения заданного времени.
В этом материале разберемся с тем, как реализовать этот подход в Tkinter с помощью метода after() , который может быть вызван во всех классах виджетов.
Следующий код показывает пример того, как функция обратного вызова может блокировать основной цикл.
Это приложение состоит из одной кнопки, которая становится неактивной после нажатия. Через 5 секунд ее снова можно нажать. Простейшая реализация будет выглядеть следующим образом:
import time
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, command=self.start_action,
text="Ждать 5 секунд")
self.button.pack(padx=50, pady=20)
def start_action(self):
self.button.config(state=tk.DISABLED)
time.sleep(5)
self.button.config(state=tk.NORMAL) if __name__ == "__main__":
app = App()
app.mainloop()
Если запустить эту программу, то можно заметить, что не кнопка становится неактивной, а весь графический интерфейс зависает на 5 секунд. Это понятно по внешнему виду кнопки, которая в течение 5 секунд выглядит нажатой, а не выключенной. Более того, строка заголовка не будет реагировать на клики мыши все это время:
Если активировать дополнительные виджеты, например, Entry и Scroll, то это поведение задело бы и их.
А теперь посмотрим, как добиться нужного поведения вместо того, чтобы блокировать выполнение потока.
Как работает планирование действий
Метод after() позволяет регистрировать функцию обратного вызова, которая вызывается после задержки, заданной в миллисекундах в основном цикле Tkinter. По сути, они представляют собой зарегистрированные сигналы-события, которые обрабатываются в те моменты, когда система находится в состоянии ожидания.
Таким образом заменим вызов time.sleep(5) на self.after(5000,callback) . Используем экземпляр self , потому что метод after() также доступен в корневом экземпляре Tk , и нет разницы в том, чтобы вызывать его из дочернего виджета:
import tkinter as tk class App(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, command=self.start_action,
text="Ждать 5 секунд")
self.button.pack(padx=50, pady=20)
def start_action(self):
self.button.config(state=tk.DISABLED)
self.after(5000, lambda: self.button.config(state=tk.NORMAL)) if __name__ == "__main__":
app = App()
app.mainloop()
Благодаря этому приложение будет реагировать вплоть до запланированного действия. Кнопка станет неактивной, но со строкой заголовка можно продолжать взаимодействовать привычным образом:
По последнему примеру можно предположить, что метод after() исполняется после заданной в миллисекундах длительности.
Однако на самом деле метод просит Tkinter зарегистрировать событие, что гарантирует, что оно не выполнится ранее намеченного времени. И если основной поток занят, то верхнего предела того, когда оно все-таки выполнится, нет.
Нужно также помнить о том, что выполнение метода продолжается сразу же после планирования действия. Следующий пример иллюстрирует такое поведение:
print("Первый")
self.after(1000, lambda: print("Третий"))
print("Второй")
Этот код выведет «Первый», «Второй» и, наконец, «Третий» спустя секунду. Все это время графический интерфейс будет оставаться доступным, а пользователи смогут продолжать взаимодействовать с ним.
Обычно нужно также не допустить, чтобы одно и то же фоновое задание выполнялось более одного раза, поэтому хорошей практикой считается отключение виджета, запустившего выполнение.
Не стоит забывать, что любая запланированная функция будет выполнена в основном потоке, поэтому одного только after() недостаточно, чтобы предотвратить зависание интерфейса. Нужно также не выполнять методы, выполнение которых занимает много времени в качестве обратного вызова.
В следующем примере рассмотрим, как можно сделать так, чтобы эти блокирующие действия выполнялись в отдельных потоках.
Метод after() возвращает идентификатор запланированного события, который можно передать в метод after_cancel() для отмены выполнения функции обратного вызова.
Дальше рассмотрим, как реализовать остановку запланированного события с помощью этого метода.
Работа в потоках
Поскольку основной поток отвечает только за обновление графического интерфейса и обработку событий, оставшаяся часть фоновых событий должна выполняться на разных потоках.
Стандартная библиотека Python включает модуль threading для создания и контроля несколько потоков с помощью высокоуровневого интерфейса, который позволяет работать с простыми классами и методами.
Стоит отметить, что CPython — «эталонная реализация» Python — ограничена GIL (Global Interpreter Lock), механизмом, который не дает нескольким потокам запускать байт-код Python одновременно. Из-за этого невозможно пользоваться преимуществами многопроцессорных систем. Об этом важно помнить при попытке улучшить производительность приложения.
В следующем примере объединены приостановка потока с помощью time.sleep() , а также действие, запланированное с помощью after() :
import time
import threading
import tkinter as tk class App(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, command=self.start_action,
text="Ждать 5 секунд")
self.button.pack(padx=50, pady=20)
def start_action(self):
self.button.config(state=tk.DISABLED)
thread = threading.Thread(target=self.run_action)
print(threading.main_thread().name)
print(thread.name)
thread.start()
self.check_thread(thread)
def check_thread(self, thread):
if thread.is_alive():
self.after(100, lambda: self.check_thread(thread))
else:
self.button.config(state=tk.NORMAL)
def run_action(self):
print("Запуск длительного действия. ")
time.sleep(5)
print("Длительное действие завершено!") if __name__ == "__main__":
app = App()
app.mainloop()
Как работают треды
Для создания нового объекта Thread можно использовать конструктор и аргумент-ключевое слово target . Он будет вызван на отдельном потоке при использовании его же метода start() .
В прошлом примере использовалась ссылка на метод run_action , примененная экземпляру текущего приложения:
Источник: pythonru.com
>»>