Fundamentals 8 min read

Unlocking Python Coroutines: From Basics to Real-World File Search

This tutorial explains what coroutines are, compares their pros and cons, shows how to implement them in Python with yield, next() and send(), and demonstrates a practical file‑search utility built with procedural programming and generators.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Unlocking Python Coroutines: From Basics to Real-World File Search

1. Coroutines

Coroutines, also called micro‑threads or fibers, are lightweight user‑level threads. Unlike system‑level threads scheduled by the OS, coroutines are scheduled by the programmer within a single thread, allowing a function to pause its execution, run another function, and later resume from the exact point it stopped.

Technically, a coroutine has its own register context and stack; when a switch occurs the context and stack are saved elsewhere and restored on the next activation, preserving the state of all local variables.

1.2 Advantages and Disadvantages

No thread‑context‑switch overhead, which can improve performance, though the programmer must handle scheduling and coroutines cannot automatically use multiple CPUs.

No need for atomic locks or synchronization.

Simplifies control‑flow switching and programming model.

High concurrency and scalability: a single CPU can manage thousands of coroutines, making them ideal for high‑concurrency workloads.

Cannot utilize multiple cores directly; a coroutine runs on a single thread and needs a process to leverage multi‑CPU.

Blocking operations (e.g., I/O) block the entire program.

2. Implementing Coroutines with yield

Python's yield expression enables the pause‑and‑resume behavior described above. The function is first initialized with next(), which runs it up to the first yield. Subsequent send() calls both resume execution and provide a value to the yield expression.

Each next() or send() continues the function from the last pause point.

Images illustrate the generator creation, execution results, and the need to call next() before send():

3. Procedural Programming

Procedural programming focuses on a sequence of steps (procedures) to solve a problem, resembling an assembly line. It emphasizes clear architecture and reduced complexity, but suffers from poor extensibility, making it suitable for software that rarely changes (e.g., kernels, web servers).

Application: Implementing a "grep -rl error" Utility

The goal is to search a directory tree for files containing the word "error". The process follows five stages:

Find absolute paths of all files using os.walk (returns a tuple of path, directories, files).

Open each file.

Iterate over each line.

Filter lines that contain "error".

Print the filename of matching lines.

Images show each stage and the final output.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

coroutineFile SearchYieldprocedural programming
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.