Sobes.tech
Junior

What is concurrency in the context of programming?

sobes.tech AI

Answer from AI

Concurrency in programming is the ability of a system to handle multiple tasks (or threads of execution) in such a way that they appear to be executing simultaneously. This is achieved through task switching rather than strict sequential execution.

Concurrency does not mean true parallel execution, which requires a multi-processor environment. Concurrency is more about structuring programs to efficiently utilize available resources (e.g., waiting for input/output).

In Python, the main mechanisms for implementing concurrency are:

  • Threads: Use standard operating system threads within a single process. They are subject to GIL (Global Interpreter Lock), which limits true parallel execution of CPU-bound tasks on multi-core processors. Suitable for I/O-bound tasks (network requests, file operations).
  • Processes: Create separate OS processes, each with its own address space. They bypass GIL, allowing true parallel execution of CPU-bound tasks. They require more resources and are more complex for data sharing.
  • Asyncio: Uses a single thread for non-blocking I/O. Based on cooperative multitasking, where tasks explicitly "yield" control to other tasks, waiting for I/O operations to complete. Effective for high-load applications with many long I/O operations.

Comparison of mechanisms:

Mechanism Isolation GIL Context Switching Use Cases
Threads Low Yes OS (preemptive) I/O-bound tasks (network, disk)
Processes High No OS (preemptive) CPU-bound tasks
Asyncio High No Cooperative High-load I/O bound applications (servers)
# Example of using threads for concurrent file downloading
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() # Wait for all threads to finish

print("All files downloaded.")
# Example of using processes for CPU-bound tasks
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__": # Important for multiprocessing in 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() # Wait for all processes to finish

    print("All calculations finished.")
# Example of using asyncio for concurrent execution of asynchronous tasks
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())
What is concurrency in the context of programming… - sobes.tech