Назад к вопросам
Junior
69
questionbank

Что такое конкурентность в контексте программирования?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Конкурентность в программировании — это способность системы обрабатывать множество задач (или потоков выполнения) таким способом, что они кажутся выполняющимися одновременно. Это достигается за счет переключения между задачами, а не их строго последовательного выполнения.

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

В Python основные механизмы для реализации конкурентности:

  • Потоки (Threads): Используют стандартные потоки операционной системы внутри одного процесса. Подвержены GIL (Global Interpreter Lock), который ограничивает истинное параллельное выполнение вычислительно-интенсивных задач на многоядерных процессорах. Хорошо подходят для задач, связанных с вводом-выводом (сетевые запросы, работа с файлами).
  • Процессы (Processes): Создают отдельные процессы операционной системы, каждый со своим адресным пространством. Обходят GIL, позволяя истинное параллельное выполнение вычислительно-интенсивных задач. Требуют больше ресурсов и сложнее для обмена данными между процессами.
  • Асинхронное программирование (Asyncio): Использует один поток выполнения для неблокирующего ввода-вывода. Основано на кооперативной многозадачности, где задачи явно "отдают" управление другим задачам, ожидая завершения операции ввода-вывода. Эффективно для высоконагруженных приложений с большим количеством долгих операций ввода-вывода.

Сравнение механизмов:

Механизм Изоляция GIL Переключение Случаи использования
Потоки (Threads) Низкая Да ОС (preemptive) Ввод-вывод связанные задачи (сеть, диск)
Процессы (Processes) Высокая Нет ОС (preemptive) Вычислительно-интенсивные задачи
Асинхронность (Asyncio) Высокая Нет Кооперативное Высоконагруженные I/O bound приложения (серверы)
# Пример использования потоков для конкурентного скачивания файлов
import threading
import requests

def download_file(url, filename):
    response = requests.get(url)
    with open(filename, 'wb') as f:
        f.write(response.content)
    print(f"Downloaded {filename}")

urls = [
    "http://example.com/file1",
    "http://example.com/file2",
    "http://example.com/file3",
]
threads = []
for i, url in enumerate(urls):
    thread = threading.Thread(target=download_file, args=(url, f"file_{i}.txt"))
    threads.append(thread)
    thread.start()

for thread in threads:
    thread.join() # Ожидание завершения всех потоков

print("All files downloaded.")
# Пример использования процессов для конкурентного выполнения CPU-bound задачи
import multiprocessing
import time

def expensive_calculation(n):
    result = 0
    for i in range(n):
        result += i * i
    print(f"Finished calculation for {n}")
    return result

if __name__ == "__main__": # Важно для мультипроцессинга в Python
    numbers = [10**7, 10**7, 10**7]
    processes = []
    for num in numbers:
        process = multiprocessing.Process(target=expensive_calculation, args=(num,))
        processes.append(process)
        process.start()

    for process in processes:
        process.join() # Ожидание завершения всех процессов

    print("All calculations finished.")
# Пример использования asyncio для конкурентного выполнения асинхронных задач
import asyncio
import aiohttp

async def fetch_url(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = [
        "http://example.com",
        "http://example.org",
        "http://example.net",
    ]
    async with aiohttp.ClientSession() as session:
        tasks = [asyncio.create_task(fetch_url(session, url)) for url in urls]
        results = await asyncio.gather(*tasks)
        for url, result in zip(urls, results):
            print(f"Fetched {url}: {len(result)} bytes")

if __name__ == "__main__":
    asyncio.run(main())