Назад к вопросам
Junior
83
questionbank
Что такое конкурентность?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Способ выполнения нескольких задач, которые могут перекрываться во времени.
- Параллелизм: Задачи выполняются одновременно на разных ядрах процессора.
- Конкурентность: Задачи могут выполняться последовательно или вперемешку на одном ядре, при этом создается иллюзия одновременности.
В Python конкурентность часто реализуется с помощью:
- Потоков (Threads): Используются для ввода/вывода операций (сеть, дисковый ввод/вывод), где поток может "спать" во время ожидания, позволяя другому потоку работать. Из-за GIL (Global Interpreter Lock) потоки не обеспечивают истинный параллелизм для CPU-bound задач в стандартном CPython.
- Процессов (Processes): Используются для CPU-bound задач. Каждый процесс имеет свое независимое адресное пространство, обходит GIL и обеспечивает истинный параллелизм.
- Корутин (Coroutines) и Асинхронного программирования (asyncio): Легковесные задачи, которые кооперативно переключаются. Идеально подходят для высоконагруженных I/O-bound приложений.
| Механизм | Использование | Параллелизм (CPU-bound) | GIL (CPython) | Переключение | Затраты ресурсов |
|---|---|---|---|---|---|
| Потоки | I/O-bound | Нет (из-за GIL) | Влияет | Планировщиком ОС | Высокие |
| Процессы | CPU-bound, I/O-bound | Да | Обходится | Планировщиком ОС | Очень высокие |
| Корутины | I/O-bound, Высоконагр. | Нет | Не влияет | Явное (await) |
Низкие |
# Пример использования потоков для I/O-bound задачи
import threading
import time
def download_data(url):
# Имитация сетевого запроса
print(f"Начинается загрузка с {url}")
time.sleep(2) # Имитация ожидания I/O
print(f"Загрузка с {url} завершена")
urls = ["http://site1.com", "http://site2.com", "http://site3.com"]
threads = []
for url in urls:
thread = threading.Thread(target=download_data, args=(url,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join() # Ждем завершения всех потоков
print("Все загрузки завершены.")
# Пример использования процессов для CPU-bound задачи
import multiprocessing
import time
def calculate_square(number):
# Имитация CPU-bound вычисления
print(f"Начинается вычисление квадрата {number}")
result = number * number
time.sleep(1) # Имитация работы CPU
print(f"Квадрат {number} - {result}")
return result
numbers = [1, 2, 3, 4]
pool = multiprocessing.Pool(processes=2) # Используем 2 процесса
results = pool.map(calculate_square, numbers)
pool.close()
pool.join()
print(f"Все вычисления завершены. Результаты: {results}")
# Пример использования asyncio для I/O-bound задачи
import asyncio
async def download_data_async(url):
# Имитация асинхронной сетевой операции
print(f"Начинается асинхронная загрузка с {url}")
await asyncio.sleep(2) # Имитация асинхронного ожидания I/O
print(f"Асинхронная загрузка с {url} завершена")
async def main():
urls = ["http://site1.com", "http://site2.com", "http://site3.com"]
tasks = [download_data_async(url) for url in urls]
await asyncio.gather(*tasks) # Запускаем задачи параллельно (конкурентно)
print("Запуск асинхронных загрузок...")
asyncio.run(main())
print("Все асинхронные загрузки завершены.")
Конкурентность позволяет эффективно использовать ресурсы, особенно при наличии операций ввода/вывода, избегая простоя процессора.