Python threading thread daemon

How to Use Daemon Threads in Python

In this tutorial you will discover how to create, configure and use daemon threads in Python.

Need for Daemon Threads

A thread is a thread of execution in a computer program.

Every Python program has at least one thread of execution called the main thread. Both processes and threads are created and managed by the underlying operating system.

Sometimes we may need to create additional threads in our program in order to execute code concurrently.

Python provides the ability to create and manage new threads via the threading module and the threading.Thread class.

You can learn more about Python threads in the guude:

In concurrent programming, we may need to execute sporadic, periodic or long-running tasks in the background.

A special type of thread is used for background tasks, called a daemon thread.

What is a daemon thread and how can we use it in Python?

Run your loops using all CPUs, download my FREE book to learn how.

What is a Daemon Thread

A daemon thread is a background thread.

Daemon is pronounced “dee-mon“, like the alternate spelling “demon“.

The ideas is that backgrounds are like “daemons” or spirits (from the ancient Greek) that do tasks for you in the background. You might also refer to daemon threads as daemonic.

A thread may be configured to be a daemon or not, and most threads in concurrent programming, including the main thread, are non-daemon threads (not background threads) by default.

The property of being a daemon thread or not is supported by the underlying operating system that actually creates and manages the execution of threads.

Daemon threads are helpful for executing tasks in the background to support the non-daemon threads in an application.

Uses of daemon threads might include:

  • Background logging to file or database.
  • Background data retrieval, updates, refresh.
  • Background data storage to disk or database.

Background tasks can be varied in type and specific to your application.

Some properties of these tasks might include:

  • Sporadic: Tasks that run only when specific conditions arise (e.g. ad hoc logging).
  • Periodic: Tasks that run after a consistent interval (e.g. data save/load every minute).
  • Long-Running: Tasks that run for the duration of the program (e.g. monitoring a resource).
Читайте также:  Html как расположить кнопку

Typically daemon threads execute non-critical tasks that although may be useful to the application are not critical if they fail (perhaps silently) or are canceled mid-operation.

By definition, a daemon thread will not have control over when it is terminated. The program will terminate once all non-daemon threads finish, even if there are daemon threads still running. Therefore, the code it executes must be robust to arbitrary termination, such as the flushing and closing of external resources like streams and files that may not be closed correctly.

Now that we know what daemon threads are, let’s compare them to non-daemon threads.

Confused by the threading module API?
Download my FREE PDF cheat sheet

Daemon vs Non-Daemon Threads

We can better understand daemon threads by comparing them to non-daemon threads.

The difference between daemon threads and non-daemon threads is that the process will exit if only daemon threads are running, whereas it cannot exit if at least one non-daemon thread is running.

  • Daemon: A process will exit if only daemon threads are running (or if no threads are running).
  • Non-Daemon: A process will not exit if at least one non-daemon thread is running.

This property makes daemon threads suited to executing background tasks that support the application, but are not critical if they are terminated at an ad hoc time by the parent process.

Now that we understand when to use daemon threads, let’s look at how we might create them in Python.

Free Python Threading Course

Download my threading API cheat sheet and as a bonus you will get FREE access to my 7-day email course.

Discover how to use the Python threading module including how to create and start new threads and how to use a mutex locks and semaphores

How to Create Daemon Threads

A Python threading.Thread instance can be configured to be a daemon thread.

We can configure a new thread to be a daemon thread by specifying the “daemon” argument to True in the constructor of the threading.Thread class.

Источник

Параллельные потоки в Python — Daemon Thread

В сегодняшнем посте мы рассмотрим использование потоков в Python. Прежде чем мы начнем с основной темы, давайте сначала посмотрим, что такое Daemon Thread.

Daemon Thread

Что такое Daemon Thread?

Daemon Thread в Python — это тип потока, который может работать независимо в фоновом режиме. Эти виды потоков выполняются независимо от основного потока. Так что они называются неблокирующими потоками.

Когда вам могут понадобиться потоки Daemon в Python?

Предположим, вам нужно иметь длительную задачу, которая пытается читать файлы журнала. Эта задача должна предупреждать пользователя при обнаружении сообщения об ошибке в журналах.

Читайте также:  Java util arrays sort array

Мы можем назначить поток Daemon для этой задачи, который может отслеживать наши файлы журналов, в то время как наша основная программа выполняет свою обычную работу.

Самое полезное в потоках Daemon — это то, что они автоматически останавливают выполнение после завершения основной программы.

Если вам нужна короткая задача, поток Daemon прекратит выполнение после того, как вернется. Однако из-за этой природы потоки широко используются для длительных фоновых задач.

Практическая реализация

В этих примерах на Python будет использоваться модуль потоковой передачи, который является частью стандартной библиотеки.

Чтобы проиллюстрировать мощь потоков, давайте сначала создадим два потока, A и B.

Мы заставим поток A выполнить короткое вычисление, в то время как поток B будет пытаться отслеживать общий ресурс.

Если для этого ресурса установлено значение True , мы заставим поток B предупреждать пользователя о статусе.

import threading import time # Set the resource to False initially shared_resource = False # A lock for the shared resource lock = threading.Lock() def perform_computation(): # Thread A will call this function and manipulate the resource print(f'Thread - performing some computation. ') shared_resource = True print(f'Thread - set shared_resource to True!') print(f'Thread - Finished!') time.sleep(1) def monitor_resource(): # Thread B will monitor the shared resource while shared_resource == False: time.sleep(1) print(f'Thread - Detected shared_resource = False') time.sleep(1) print(f'Thread - Finished!') if __name__ == '__main__': a = threading.Thread(target=perform_computation, name='A') b = threading.Thread(target=monitor_resource, name='B') # Now start both threads a.start() b.start()

Здесь поток A установит shared_resource в True , а поток B будет ждать, пока этот ресурс не станет True.

Thread A - performing some computation. Thread A - set shared_resource to True! Thread A - Finished! Thread B - Detected shared_resource = False Thread B - Finished!

Обратите внимание, что оба потока являются обычными потоками.

Теперь давайте сделаем поток B потоком демона. Посмотрим, что теперь будет. Для этого мы можем установить его как параметр в методе threading.Thread(daemon=True) .

import threading import time shared_resource = False # Set the resource to False initially lock = threading.Lock() # A lock for the shared resource def perform_computation(): # Thread A will call this function and manipulate the resource print(f'Thread - performing some computation. ') shared_resource = True print(f'Thread - set shared_resource to True!') print(f'Thread - Finished!') time.sleep(1) def monitor_resource(): # Thread B will monitor the shared resource while shared_resource == False: time.sleep(1) print(f'Daemon Thread - Detected shared_resource = False') time.sleep(1) print(f'Daemon Thread - Finished!') if __name__ == '__main__': a = threading.Thread(target=perform_computation, name='A') b = threading.Thread(target=monitor_resource, name='B', daemon=True) # Make thread B as a daemon thread # Now start both threads a.start() b.start()
Thread A - performing some computation. Thread A - set shared_resource to True! Thread A - Finished! Daemon Thread B - Detected shared_resource = False

Обратите внимание, что Daemon Thread не завершается. Это потому, что он будет автоматически убит основным потоком. Неблокирующая природа потоков делает их очень полезными для многих приложений Python.

Читайте также:  Java annotations on interfaces

Источник

Потоки-демоны в Python

В Python у каждой программы есть как минимум один поток — главный поток. Чтобы создать программу, у которой будет больше одного потока, используется модуль threading . Используя несколько потоков в программе, вы можете выполнять задачи параллельно.

Иногда выполнить задачу задачу нужно в фоновом режиме. Для этого используется специальный вид потока — поток-демон.

Потоки-демоны — это потоки, которые выполняют задачи в фоновом режиме.

Потоки-демоны полезны для таких выполнения задач:

  • Запись информации в файл в фоновом режиме.
  • Скраппинг содержимого веб-сайта в фоновом режиме.
  • Автоматическое сохранение данных в базе данных в фоновом режиме.

Создание потока-демона

Чтобы создать поток-демон, в конструкторе Thread нужно указать аргумент daemon=True :

t = Thread(target=f, deamon=True)

Это также можно сделать после создания экземпляра Thread — достаточно установить свойство daemon равным True .

t = Thread(target=f) t.deamon = True

Пример недемонического потока

Давайте создадим поток, не являющийся демоном, который показывает количество секунд ожидания программы:

from threading import Thread import time def show_timer(): count = 0 while True: count += 1 time.sleep(1) print(f'Прошло секунд. ') t = Thread(target=show_timer, daemon=True) t.start() answer = input('Вы хотите выйти?\n')

Как это работает

1. Создадим функцию show_timer() , которая отображает количество секунд ожидания программы.

2. Создадим новый поток, выполняющий функцию show_timer() :

t = Thread(target=show_timer) 

4. Вызываем функцию input() , чтобы попросить пользователя ввести данные:

answer = input('Вы хотите выйти?\n') 

Если вы запустите программу, она будет работать вечно.

Вы хотите выйти?
Прошло 1 секунд.
Прошло 2 секунд.
Прошло 3 секунд.
Прошло 4 секунд.
Y
Прошло 5 секунд.
Прошло 6 секунд.

Чтобы завершить программу, нужно закрыть терминал.

Программа работает неопределенно долго, потому что поток t является недемоническим потоком. Программа должна дождаться завершения всех недемонических потоков, прежде чем она сможет выйти.

Пример потока-демона

Теперь давайте превратим поток, с которым разбирались выше, в поток-демон:

from threading import Thread import time def show_timer(): count = 0 while True: count += 1 time.sleep(1) print(f'Пршло секунд. ') t = Thread(target=show_timer, daemon=True) t.start() answer = input('Вы хотите выйти?\n')

Если запустить программу, ввести что-то и нажать Enter, программа завершится.

Вы хотите выйти? 
Прошло 1 секунд.
Y

Программа завершается, потому что ей не нужно ждать завершения работы потока-демона. Кроме того, поток-демон автоматически завершается при выходе программы.

Потоки демоны и недемонические потоки: отличия

Критерий сравнения Поток-демон Недемонический поток
Создание потока t = Thread(target=f, daemon=True) t = Thread(target=f)
Программа ждет завершения перед выходом Нет Да
Для каких задач подходит Некритичные. Например, запись логов Критичные

Что нужно запомнить

  • Поток-демон — это поток, который выполняет задачи в фоновом режиме.
  • Потоки-демоны полезны для выполнения задач, которые не являются критическими.
  • Программа не ждет завершения работы потока-демона перед завершением.
  • При завершении программы поток-демон автоматически завершается.

СodeСhick.io — простой и эффективный способ изучения программирования.

2023 © ООО «Алгоритмы и практика»

Источник

Оцените статью