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())