Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Understanding Multiprocessing, Multithreading, and Coroutines in Python

Tech 1

Multiprocessing Fundamentals

A process represents an executing application within the operating system, serving as an independent entity for resource allocation with its own memory space. While a single process can contain multiple threads sharing the process's stack, multiprocessing enables true parallelism by utilizing separate processes.

Example implementation using multiprocessing:

import random
import time
from multiprocessing import Process

def fetch_data(file_name):
    print(f'Downloading {file_name}...')
    duration = random.randint(5, 10)
    time.sleep(duration)
    print(f'{file_name} downloaded in {duration} seconds')

def execute_parallel_tasks():
    initial_time = time.time()
    
    process_one = Process(target=fetch_data, args=("Advanced_Python_Guide.pdf",))
    process_two = Process(target=fetch_data, args=("Demo_Video.mp4",))
    
    process_one.start()
    process_two.start()
    
    process_one.join()
    process_two.join()
    
    final_time = time.time()
    print(f'Total execution time: {final_time - initial_time:.2f} seconds')

if __name__ == '__main__':
    execute_parallel_tasks()

Key multiprocessing components:

  • Process: Creates process instances
  • target: Specifies the function to execute
  • args: Tuple containing function arguments
  • start(): Initiates process execution
  • join(): Blocks until process completion

Multithreading Concepts

Multithreading enables concurrent execution of multiple threads within a single proces, leveraging hardware capabilities for improved performance.

Benefits include:

  1. Background processing of time-intensive operations
  2. Enhanced system responsiveness on multi-core architectures

Thread-based implementation example:

import random
import time
from threading import Thread

def retrieve_content(document_name):
    print(f'Retrieving {document_name}...')
    wait_period = random.randint(5, 10)
    time.sleep(wait_period)
    print(f'{document_name} retrieved in {wait_period} seconds')

def run_concurrent_threads():
    begin_time = time.time()
    
    thread_a = Thread(target=retrieve_content, args=("Python_Development_Handbook.pdf",))
    thread_b = Thread(target=retrieve_content, args=("Sample_Movie.avi",))
    
    thread_a.start()
    thread_b.start()
    
    thread_a.join()
    thread_b.join()
    
    finish_time = time.time()
    print(f'Overall duration: {finish_time - begin_time:.2f} seconds')

if __name__ == '__main__':
    run_concurrent_threads()

Coroutine Implementation

Coroutines provide lightweight concurrency mechanisms that optimize resource usage compared to traditional threading. They enable cooperative multitasking where execution switches only when tasks encounter blocking operations.

Core asyncio concepts:

  • Event loop: Continuously monitors and executes coroutine functions
  • Coroutine object: Created using async keyword, representing suspended execution
  • Task: Enhanced coroutine wrapper for better management
  • Future: Represents eventual result of asynchronous operation
  • async/await: Keywords for defining and managing coroutines

Coroutine demonstration:

import asyncio
import random
import time

async def handle_download(resource_name):
    print(f'Starting download of {resource_name}...')
    processing_time = random.randint(5, 10)
    await asyncio.sleep(processing_time)
    print(f'{resource_name} downloaded in {processing_time} seconds')

async def orchestrate_downloads():
    start_timestamp = time.time()
    
    task_one = handle_download("Comprehensive_Python_Manual.pdf")
    task_two = handle_download("Presentation_Video.mp4")
    
    await asyncio.gather(task_one, task_two)
    
    end_timestamp = time.time()
    print(f'Combined execution time: {end_timestamp - start_timestamp:.2f} seconds')

if __name__ == '__main__':
    event_loop = asyncio.get_event_loop()
    try:
        event_loop.run_until_complete(orchestrate_downloads())
    finally:
        event_loop.close()

Essential coroutine workflow:

  1. Define functions with async keyword
  2. Create coroutine objects through function calls
  3. Obtain event loop via asyncio.get_event_loop()
  4. Execute coroutines using run_until_complete()

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.