Target Audience:
This course is for more experienced Python programmers.
Attendees are expected to already be familiar with the core
Python language and common library modules such
as os, sys, etc. Having some basic
knowledge of network programming principles is recommended.
Next Course Date:
Price: $1795
What's Included?
- A printed copy of the course notes.
- A copy of the "Python Essential Reference, 4th Ed."
- Breakfast and lunch at local restaurants
- Snacks
[ More Information | FAQ]
|
Python Networking, Concurrency, and Distributed Systems
[4.5 days] Extend your Python knowledge by learning how to
write networked and distributed programs.
Topics include socket programming, internet data handling
(XML, JSON, etc.), simple web programming, WSGI, REST, actors, remote
procedure call (RPC), message passing, map-reduce,
distributed objects, and asynchronous I/O. The course also
includes in-depth material on concurrent programming techniques including threads, processes,
and multiprocessing. A major focus of this course is on the underlying
principles that form the foundation of the programming frameworks and applications that you may
be using now--you will walk away with new insight and ideas for improving your code.
Given the advanced nature of the material, this course will also expand your
knowledge of advanced Python programming language features including decorators,
context managers, and more.
More About This Course
This is a one-of-a-kind course that you will simply not find anywhere
else. In fact, this might be the ultimate computer systems
programming course that you wish you had taken in college. For
instance, one minute, you might be talking about an advanced Python
feature whereas the next minute, you might be discussing how it
interacts with the operating system kernel. Past participants
have described the course as being "intense."
Initially, this course started as the infamous "Python Concurrency
Workshop" from 2009--the same workshop that blew
the covers off of the Python
GIL. The course has since expanded to include more information
on network programming as well as an ever-expanding look at
distributed computing techniques. If you have been looking for a
Python course where you get to spend an entire week immersed in
diabolical systems hacking, then you won't be disappointed.
Detailed Course Outline
Day 1
- Network Fundamentals and Socket Programming.
An introduction to some basic concepts of network programming. Covers
the essential details of TCP/IP and programming with sockets. Students
will learn how to write both TCP and UDP based clients and servers.
- Client-side programming. A look at high-level library modules
that allow Python to connect to standard Internet and web-related services (e.g.,
HTTP, FTP, XML-RPC, etc.). Special attention
will be given to the urllib2 module that allows Python to interact
with web servers.
- Internet Data Handling.
A brief overview of library modules that are used to process common Internet data
formats such as HTML, XML, and JSON.
- Web Programming. The absolute basics of web programming in Python.
Topics include CGI scripting, the WSGI interface, and implementing custom HTTP servers.
Note: This section is primarily focused on how to put a web-based interface on low-level
services as might be encountered in a distributed computing environment. It does not
cover web frameworks or the problem of using Python to build a website.
- Server Design. An introduction to common server design techniques
with a focus on handling concurrent clients. Topics include
process forking, threading, and event-handling. Much of this material
serves as an introduction to more advanced topics that follow.
Day 2
- Thread Programming. Everything you wanted to know about
Python threads, but were afraid to ask. Includes the absolute basics
of using the threading module and different techniques for
using threads to carry out work. Includes detailed coverage of using
different synchronization primitives, queues, and thread pools. Also
provided detailed information on the Global Interpreter Lock (GIL),
tuning parameters, and the interaction between threads and C/C++
extension modules.
- Multiprocessing. A tour of features provided by the
multiprocessing library added in Python 2.6. Covers processes,
queues, pipes, process pools, and shared memory regions. Examples
will illustrate how multiprocessing can be used to achieve higher
performance when working on multiple CPU cores.
Day 3
- Message Passing and Data Serialization. Message
passing is a core component of distributed computation. This
section provides an in-depth look at different interprocess
communication mechanisms, their performance characteristics,
and tuning options. In addition, different approaches for
serializing Python data structures are explored. Topics include
the subprocess module, named pipes, network sockets, memory mapped regions,
pickle, marshal, structure packing, and binary I/O. The section
concludes with information on high-level messaging systems such as
ZeroMQ and AMQP.
- Distributed Programming. An in-depth tour of different
distributed programming techniques. Topics include programming with
actors, client-server computing, REST, remote procedure call,
map-reduce, and distributed objects. Also includes material on
XML-RPC and WSGI.
Day 4
- Advanced I/O handling. A look at different I/O handling
techniques including blocking, non-blocking, asynchronous, and event-driven
I/O. The primary goal of this section is to better understand the
I/O handling using by different libraries and frameworks such as asyncore, Twisted, etc.
- Generators and Coroutines. An overview of concurrent
programming using generators and coroutines. The major focus of
this section is on using generators to implement user-level task switching
and to better understand libraries based on microthreads, tasklets, green-threads,
and similarly named entities.
Day 5
- Practicum. The final half day will consist of an advanced programming project
designed to reinforce concepts covered in the course.
Course Materials
Students will receive a bound fully indexed set of lecture notes along with a complete set class exercises (distributed
electronically). All class exercises come with solution code for later study and for use during the class.
Slide Topic Index
The following table, generated automatically from the presentation
slides, gives much more detail about the material to be covered. I am
always making improvements and additions to course material so this
outline is subject to change at any time.
1. Network Fundamentals
Network Fundamentals | 1-1 |
The Problem | 1-2 |
Two Main Issues | 1-3 |
Network Addressing | 1-4 |
Standard Ports | 1-5 |
Using netstat | 1-6 |
Connections | 1-7 |
Client/Server Concept | 1-8 |
Request/Response Cycle | 1-9 |
Using Telnet | 1-10 |
Data Transport | 1-11 |
Sockets | 1-12 |
Socket Basics | 1-13 |
Socket Types | 1-14 |
Using a Socket | 1-15 |
TCP Client | 1-16 |
Server Implementation | 1-18 |
TCP Server | 1-19 |
Advanced Sockets | 1-28 |
Partial Reads/Writes | 1-29 |
Sending All Data | 1-31 |
End of Data | 1-32 |
Data Reassembly | 1-33 |
Timeouts | 1-34 |
Non-blocking Sockets | 1-35 |
Socket Options | 1-36 |
Sockets as Files | 1-37 |
Odds and Ends | 1-40 |
UDP : Datagrams | 1-41 |
UDP Server | 1-42 |
UDP Client | 1-43 |
Unix Domain Sockets | 1-44 |
Raw Sockets | 1-45 |
Sockets and Concurrency | 1-46 |
Threaded Server | 1-50 |
Forking Server (Unix) | 1-51 |
Asynchronous Server | 1-52 |
Utility Functions | 1-53 |
Omissions | 1-54 |
Discussion | 1-55 |
2. Client Programming
Client Programming | 2-1 |
Overview | 2-2 |
urllib Module | 2-3 |
urllib protocols | 2-5 |
HTML Forms | 2-6 |
Web Services | 2-8 |
Parameter Encoding | 2-9 |
Sending Parameters | 2-10 |
Response Data | 2-12 |
Response Headers | 2-13 |
Response Status | 2-14 |
urllib Limitations | 2-16 |
urllib2 Module | 2-17 |
urllib2 Example | 2-18 |
urllib2 Requests | 2-19 |
Requests with Data | 2-20 |
Request Headers | 2-21 |
urllib2 Error Handling | 2-22 |
urllib2 Openers | 2-23 |
urllib2 build_opener() | 2-24 |
Example : Login Cookies | 2-25 |
Discussion | 2-26 |
Limitations | 2-28 |
ftplib | 2-29 |
Upload to a FTP Server | 2-30 |
httplib | 2-31 |
smtplib | 2-32 |
3. Internet Data Handling
Internet Data Handling | 3-1 |
Overview | 3-2 |
CSV Files | 3-3 |
Parsing HTML | 3-5 |
Running a Parser | 3-7 |
HTML Example | 3-8 |
XML Parsing with SAX | 3-10 |
Brief XML Refresher | 3-11 |
Brief Review : XML Sample | 3-12 |
SAX Parsing | 3-13 |
Commentary | 3-15 |
XML and ElementTree | 3-17 |
Brief Review : etree Parsing | 3-18 |
Obtaining Elements | 3-19 |
Iterating over Elements | 3-20 |
Element Attributes | 3-21 |
Search Wildcards | 3-22 |
XML Namespaces | 3-24 |
cElementTree | 3-26 |
Tree Modification | 3-27 |
Tree Output | 3-28 |
Incremental Parsing | 3-29 |
XML Commentary | 3-33 |
Third Party Modules | 3-34 |
JSON | 3-37 |
Sample JSON File | 3-38 |
Processing JSON Data | 3-39 |
4. Web Programming
Web Programming Basics | 4-1 |
Introduction | 4-2 |
Overview | 4-3 |
Disclaimer | 4-4 |
HTTP Explained | 4-5 |
HTTP Client Requests | 4-6 |
HTTP Responses | 4-7 |
HTTP Protocol | 4-8 |
Content Encoding | 4-9 |
Payload Packaging | 4-10 |
Role of Python | 4-12 |
Typical Python Tasks | 4-13 |
Content Generation | 4-14 |
Example : Page Templates | 4-15 |
Commentary | 4-17 |
HTTP Servers | 4-19 |
A Simple Web Server | 4-20 |
A Web Server with CGI | 4-22 |
CGI Scripting | 4-23 |
CGI Example | 4-24 |
CGI Mechanics | 4-27 |
Classic CGI Interface | 4-28 |
CGI Query Variables | 4-29 |
cgi Module | 4-30 |
CGI Responses | 4-31 |
Note on Status Codes | 4-32 |
CGI Commentary | 4-33 |
WSGI | 4-35 |
WSGI Interface | 4-36 |
WSGI Example | 4-37 |
WSGI Applications | 4-38 |
WSGI Environment | 4-39 |
Processing WSGI Inputs | 4-41 |
WSGI Responses | 4-42 |
WSGI Content | 4-44 |
WSGI Content Encoding | 4-45 |
WSGI Deployment | 4-46 |
WSGI and CGI | 4-48 |
WSGI Deployment | 4-49 |
Customized HTTP | 4-51 |
Web Frameworks | 4-55 |
Commentary | 4-57 |
5. Advanced Networking
Advanced Networking | 5-1 |
Overview | 5-2 |
Problem with Sockets | 5-3 |
SocketServer | 5-4 |
SocketServer Example | 5-5 |
Execution Model | 5-11 |
Design Discussion | 5-13 |
Big Picture | 5-14 |
Concurrent Servers | 5-15 |
Server Mixin Classes | 5-16 |
Server Subclassing | 5-17 |
Distributed Computing | 5-19 |
Discussion | 5-20 |
XML-RPC | 5-21 |
Simple XML-RPC | 5-22 |
XML-RPC Commentary | 5-24 |
XML-RPC and Binary | 5-25 |
Serializing Python Objects | 5-27 |
pickle Module | 5-28 |
Pickling to Strings | 5-29 |
Example | 5-30 |
Pickle and Large Objects | 5-32 |
Miscellaneous Comments | 5-33 |
multiprocessing | 5-35 |
Connections | 5-36 |
Connection Use | 5-37 |
Example | 5-38 |
Commentary | 5-40 |
What about... | 5-42 |
Network Wrap-up | 5-43 |
6. Concurrency Introduction
Introduction | 6-1 |
Requirements | 6-2 |
Concurrency | 6-3 |
My Personal Interest | 6-5 |
Basic Concepts | 6-6 |
Concurrent Programming | 6-7 |
Multitasking | 6-8 |
Parallel Processing | 6-9 |
Task Execution | 6-10 |
CPU Bound Tasks | 6-11 |
I/O Bound Tasks | 6-12 |
Shared Memory | 6-13 |
Processes | 6-14 |
Distributed Computing | 6-15 |
Why Python? | 6-16 |
Some Issues | 6-17 |
Why Use Python at All? | 6-18 |
Python as a Framework | 6-19 |
Programming Productivity | 6-20 |
Performance is Irrelevant | 6-21 |
You Can Go Faster | 6-22 |
Commentary | 6-23 |
Special Cases | 6-24 |
Let's Get Started | 6-25 |
7. Thread Programming
Python Multithreading | 7-1 |
Overview | 7-2 |
Background : Threads | 7-3 |
Usage : Threads | 7-4 |
Concept: Threads | 7-5 |
Thread Basics | 7-6 |
threading Module | 7-11 |
Thread Objects | 7-12 |
Launching Thread Objects | 7-13 |
Thread Execution | 7-14 |
Joining a Thread | 7-15 |
Thread Status | 7-16 |
Interpreter Execution | 7-17 |
Daemonic Threads | 7-18 |
Killing Threads | 7-19 |
Thread Termination | 7-20 |
Returning Results | 7-22 |
The Problem | 7-23 |
Returning Results | 7-24 |
Result Objects | 7-25 |
Returning Results | 7-26 |
Returning Exceptions | 7-27 |
Results w/ Exceptions | 7-28 |
Returning Exceptions | 7-29 |
Threads and Memory | 7-31 |
Shared Memory | 7-32 |
Shared Objects | 7-33 |
Thread Local Data | 7-34 |
Interlude | 7-37 |
Debugging with Threads | 7-38 |
Setting the Thread Name | 7-39 |
Thread Logging | 7-40 |
Logging Information | 7-41 |
Nondeterminism | 7-43 |
Accessing Shared Data | 7-44 |
Race Conditions | 7-48 |
Thread Synchronization | 7-49 |
Synchronization Options | 7-50 |
Mutex Locks | 7-52 |
Use of Mutex Locks | 7-54 |
Using a Mutex Lock | 7-55 |
Locking Perils | 7-58 |
Lock Management | 7-59 |
Locks and Deadlock | 7-61 |
Special Topic: | 7-63 |
with Statement | 7-64 |
Context Management | 7-65 |
Context Mgr: Locking | 7-67 |
Exception Handling | 7-68 |
Where to Put Locks? | 7-70 |
Locking Costs | 7-71 |
Contested Locking | 7-72 |
RLock | 7-73 |
RLock Example | 7-74 |
Commentary | 7-75 |
Special Topic: | 7-76 |
Background | 7-77 |
Decorators | 7-78 |
A Decorator for Locking | 7-79 |
Discussion | 7-80 |
An Example | 7-81 |
Decorators with Arguments | 7-82 |
Semaphores | 7-85 |
Semaphore Uses | 7-86 |
Resource Control | 7-87 |
Thread Signaling | 7-88 |
Events | 7-91 |
Barrier Synchronization | 7-92 |
Event Waiting | 7-93 |
Condition Variables | 7-95 |
Interlude | 7-100 |
Threads and Queues | 7-101 |
Queue Library Module | 7-102 |
Queue Usage | 7-103 |
Queue Completion | 7-104 |
Queue Programming | 7-105 |
Example: Thread Pools | 7-106 |
An Inconvenient Truth | 7-108 |
A Performance Test | 7-109 |
Bizarre Results | 7-110 |
Threads Explained | 7-112 |
What is a Thread? | 7-113 |
The Infamous GIL | 7-114 |
GIL Behavior | 7-115 |
CPU Bound Processing | 7-116 |
The Check Interval | 7-117 |
The Periodic Check | 7-118 |
What is a "Tick?" | 7-119 |
Tick Execution | 7-120 |
CPU-Bound Threads | 7-121 |
Multicore GIL Contention | 7-122 |
GIL Contention Effect | 7-123 |
Multiple CPU Cores | 7-124 |
Is There A Fix? | 7-125 |
The GIL and C Code | 7-126 |
The GIL and C Extensions | 7-127 |
How to Release the GIL | 7-128 |
The GIL and C Extensions | 7-129 |
Some Lessons Learned | 7-133 |
Using Threads | 7-134 |
I/O Bound Processing | 7-135 |
Thread Limits | 7-137 |
Check Interval Tuning | 7-138 |
Thread Memory Use | 7-139 |
Thread Stack Space | 7-140 |
Final Comments | 7-141 |
8. Messaging and Data Serialization
Message Passing | 8-1 |
Concept: Message Passing | 8-2 |
Commentary | 8-3 |
Message Passing | 8-4 |
Problem Decomposition | 8-5 |
Example : Dataflow | 8-6 |
Example : Worker Pool | 8-8 |
Example : Map-Reduce | 8-10 |
Example : Decomposed Data | 8-11 |
Comments | 8-13 |
Sending Messages | 8-14 |
A Problem | 8-15 |
Section Focus | 8-16 |
Some Tricky Bits | 8-17 |
Preview | 8-18 |
Messaging Basics | 8-19 |
What is a Message? | 8-20 |
Message Transport | 8-21 |
Pipes | 8-22 |
An Example | 8-23 |
Named Pipes/FIFOs | 8-24 |
Pipe Performance | 8-25 |
Sockets | 8-26 |
Using Sockets | 8-27 |
A File Caution | 8-28 |
Memory Mapped Regions | 8-31 |
Data Overlay | 8-33 |
mmap Commentary | 8-34 |
Using mmap | 8-35 |
Message Encoding | 8-37 |
Object Serialization | 8-38 |
The Problem | 8-39 |
pickle Module | 8-40 |
Some Pickle Issues | 8-43 |
cPickle vs. Pickle | 8-44 |
Pickle Encodings | 8-46 |
Selecting a Protocol | 8-47 |
Pickling to Strings | 8-50 |
Pickling Instances | 8-51 |
Python and References | 8-53 |
Reference Example | 8-54 |
Pickle and References | 8-55 |
Preserving References | 8-57 |
Pickler Objects | 8-58 |
Pickler Caution | 8-59 |
Pickle and Large Objects | 8-60 |
Classes and Functions | 8-61 |
Miscellaneous Comments | 8-62 |
Customizing Pickle | 8-64 |
Simple Pickling | 8-65 |
Advanced Pickling | 8-66 |
Foreign Objects | 8-68 |
struct module | 8-69 |
Structure Alignment | 8-73 |
Packing Binary Records | 8-74 |
Unpacking Records | 8-75 |
Performance Tip | 8-76 |
struct Cautions | 8-77 |
Binary Arrays | 8-79 |
ByteArray Objects | 8-80 |
Direct Array Output | 8-81 |
Direct Array Input | 8-82 |
ctypes module | 8-84 |
ctypes Types | 8-85 |
ctypes module | 8-86 |
ctypes Caution | 8-88 |
buffer() function | 8-90 |
buffer() Function | 8-91 |
Using buffer() | 8-92 |
Recognizing Buffers | 8-95 |
Messaging Wrap up | 8-97 |
9. Multiprocessing
Multiprocessing | 9-1 |
multiprocessing Module | 9-2 |
Multiprocessing Tour | 9-4 |
Processes | 9-5 |
Functions as Processes | 9-6 |
multiprocessing Example | 9-7 |
Launching Processes | 9-8 |
Does it Work? | 9-9 |
Other Process Features | 9-10 |
Process Creation | 9-11 |
A Caution | 9-12 |
Distributed Memory | 9-15 |
Synchronization Primitives | 9-16 |
Message Queues | 9-17 |
Joinable Queues | 9-18 |
Queue Example | 9-19 |
Commentary | 9-21 |
Pipes | 9-23 |
Using Pipes | 9-24 |
Pipe Setup | 9-25 |
Advice | 9-26 |
Pipe Example | 9-27 |
Pipes vs. Queues | 9-29 |
Process Pools | 9-31 |
Async Results | 9-35 |
Process Pools | 9-36 |
Using Process Pools | 9-38 |
Shared Data | 9-40 |
Shared Example | 9-41 |
Shared Arrays | 9-42 |
Locking Performance | 9-43 |
Lock-Free Sharing | 9-44 |
Wrap Up | 9-45 |
10. Distributed Programming
Distributed Programming | 10-1 |
Introduction | 10-2 |
A Problem | 10-3 |
Commentary | 10-4 |
Overview | 10-5 |
Major Topics | 10-6 |
Actor Programming | 10-7 |
Actors | 10-8 |
Features of Actors | 10-9 |
Actor History | 10-10 |
Disclosure | 10-11 |
Actor Implementation | 10-12 |
Note on APIs | 10-13 |
An Example | 10-14 |
Another Example | 10-15 |
Using Actors | 10-16 |
A Problem | 10-18 |
Actor Runtime | 10-19 |
Async Messaging | 10-20 |
Concurrency | 10-21 |
Implementing the Runtime | 10-22 |
Example: Threaded Actor | 10-23 |
Actors and Processes | 10-29 |
Process Issues | 10-30 |
Actor Addressing | 10-32 |
Actor Naming | 10-33 |
Names and Wrappers | 10-36 |
Name Registry | 10-38 |
Message Addressing | 10-40 |
Implementing send() | 10-41 |
Examples | 10-42 |
Distributed Actors | 10-44 |
Connection Objects | 10-45 |
Distributed Send | 10-49 |
Proxy Actors | 10-50 |
Proxy Implementation | 10-51 |
Using a Proxy | 10-52 |
Message Dispatching | 10-53 |
Message Dispatcher | 10-54 |
Using the Dispatcher | 10-59 |
Putting it All Together | 10-60 |
Big Picture | 10-61 |
Tricky Bits With Actors | 10-63 |
What's in a Message? | 10-64 |
Instances and Messages | 10-65 |
Don't Do It! | 10-69 |
Actor Naming | 10-70 |
Name Registry | 10-71 |
Registry Details | 10-72 |
Concurrency Alternatives | 10-73 |
Optional Concurrency | 10-74 |
Concurrency Alternatives | 10-76 |
Hard Problems | 10-77 |
Actor Commentary | 10-79 |
Some Links | 10-80 |
Client/Server Computing | 10-81 |
Client/Server Comments | 10-83 |
RESTful Services | 10-84 |
REST Resources | 10-85 |
Resource Representation | 10-86 |
REST Actions | 10-87 |
REST Examples | 10-88 |
Stateless Implementation | 10-90 |
Reuse of HTTP | 10-91 |
Implementing REST | 10-92 |
Example with WSGI | 10-93 |
Running an WSGI App | 10-98 |
REST Links | 10-99 |
Remote Procedure Call | 10-101 |
XML-RPC | 10-104 |
Simple XML-RPC | 10-105 |
XML-RPC Commentary | 10-107 |
XML-RPC and Binary | 10-108 |
XML-RPC and Instances | 10-109 |
Some Issues | 10-110 |
RPC Libraries | 10-111 |
Problems with Objects | 10-113 |
Distributed Objects | 10-114 |
Server Instances | 10-116 |
Server Dispatching | 10-117 |
Client Proxies | 10-118 |
Object Registry | 10-119 |
Proxy Creation/Lookup | 10-120 |
Various Problems | 10-122 |
Object Managers | 10-123 |
Managers | 10-124 |
Using a Manager | 10-125 |
Manager Example | 10-126 |
Commentary | 10-131 |
Hard Problems | 10-132 |
Some Resources | 10-133 |
Resources | 10-134 |
Final Comments | 10-135 |
11. Advanced I/O
Advanced I/O Handling | 11-1 |
Introduction | 11-2 |
Disclaimers | 11-3 |
Goal | 11-4 |
I/O Basics | 11-5 |
Blocking I/O | 11-6 |
Blocking I/O Rules | 11-9 |
Caution : Partial Sends | 11-10 |
Socket Tuning Parameters | 11-11 |
Non-blocking I/O | 11-13 |
Non-blocking Sockets | 11-14 |
Using Non-blocking I/O | 11-15 |
Overlapped I/O | 11-16 |
Overlapped I/O Example | 11-17 |
Commentary | 11-18 |
Asynchronous I/O | 11-20 |
Commentary | 11-22 |
I/O Polling/Multiplexing | 11-23 |
select module | 11-24 |
select() function | 11-25 |
select() performance | 11-28 |
A select() limitation | 11-30 |
Event Driven I/O | 11-32 |
Event Driven "Tasks" | 11-35 |
Multitasking | 11-38 |
Example : Time Server | 11-39 |
A Complication | 11-42 |
Solution | 11-43 |
Example : Echo Server | 11-44 |
Commentary | 11-49 |
Events and Asyncore | 11-50 |
Using Asyncore | 11-51 |
Twisted | 11-52 |
Twisted Example | 11-53 |
Event Driven Problems | 11-54 |
Scaling Problems | 11-55 |
Some Solutions | 11-57 |
A Scaling Benefit | 11-58 |
Long-Running Calculations | 11-59 |
Blocking Operations | 11-60 |
The Blocking Problem | 11-61 |
Incremental Feeding | 11-63 |
Events and Threads | 11-64 |
Interoperability Problems | 11-66 |
Personal Bias | 11-67 |
Commentary | 11-68 |
12. Generators and Coroutines
Generators and Coroutines | 12-1 |
Introduction | 12-2 |
Reference Material | 12-3 |
Background Material | 12-4 |
Generators | 12-5 |
Generator Functions | 12-7 |
A Practical Example | 12-9 |
Generators as Pipelines | 12-10 |
A Pipeline Example | 12-11 |
Yield as an Expression | 12-12 |
Coroutines | 12-13 |
Coroutine Execution | 12-14 |
Coroutine Priming | 12-15 |
Using a Decorator | 12-16 |
Processing Pipelines | 12-17 |
An Example | 12-18 |
Generators as Tasks | 12-21 |
Program Execution | 12-22 |
Task Switching | 12-23 |
An Insight | 12-24 |
Multitasking Example | 12-25 |
Scheduling Example | 12-26 |
Yielding For I/O | 12-29 |
More About Yield | 12-30 |
Talking to the Scheduler | 12-31 |
An Example Task | 12-32 |
Signaling an I/O Request | 12-33 |
Implementing I/O Waits | 12-35 |
Building a Scheduler | 12-36 |
Example : Time Server | 12-44 |
Example : Echo Server | 12-45 |
Comments | 12-48 |
Problems | 12-50 |
Some Links | 12-52 |
More Information | 12-53 |
|