Title: COTS Challenges for Embedded Systems
1E81 CSE 532S Advanced Multi-Paradigm Software
Development
Proactor Pattern
Venkita Subramonian Christopher Gill Department
of Computer Science and Engineering Washington
University, St. Louis cdgill_at_cse.wustl.edu
2Proactor
- An architectural pattern for asynchronous,
decoupled operation initiation and completion - In contrast to Reactor architectural pattern
- Synchronous, coupled initiation and completion
- I.e., reactive initiation completes when hander
call returns - Except for reactive completion only, e.g., for
connector - Proactor separates initiation and completion more
- Without multi-threading overhead/complexity
- Performs additional bookkeeping to match them up
- Dispatches a service handler upon completion
- Asynch Handler does post-operation processing
- Still separates application from infrastructure
- A small departure vs. discussing other patterns
- Well focus on using rather than implementing
proactor - I.e., much of the implementation already given by
the OS
3Context
- Asynchronous operations used by application
- Application thread should not block
- Application needs to know when an operation
completes - Decoupling application/infrastructure is useful
- Reactive performance is insufficient
- Multi-threading incurs excessive overhead or
programming model complexity
4Design Forces
- Separation of application from infrastructure
- Flexibility to add new application components
- Performance benefits of concurrency
- Reactive has coarse interleaving (handlers)
- Multi-threaded has fine interleaving
(instructions) - Complexity of multi-threading
- Concurrency hazards deadlock, race conditions
- Coordination of multiple threads
- Performance issues with multi-threading
- Synchronization re-introduces coarser granularity
- Overhead of thread context switches
- Sharing resources across multiple threads
5Compare Reactor vs. Proactor Side by Side
Reactor
Proactor
Application
Application
ASYNCH accept/read/write
handle_events
Reactor
Handle
handle_event
handle_events
Event Handler
Proactor
accept/read/write
handle_event
Handle
Completion Handler
6Proactor in a nutshell
create handlers
Completion Handler2
Completion Handler1
Application
Proactor
I/O Completion port
OS (or AIO emulation)
7Motivating Example A Web Server
From http//www.cs.wustl.edu/schmidt/PDF/proactor
.pdf
8First Approach Reactive (1/2)
Web Server
Acceptor
HTTP Handler
Web Browser
Reactor
9First Approach Reactive (2/2)
Web Server
read request
3
parse request
4
Acceptor
1
HTTP Handler
Web Browser
GET/etc/passwd
5
socket read ready
send file
register for file read
2
10
8
register for socket write
7
read file
Reactor
6
file read ready
File System
9
socket write ready
10Analysis of the Reactive Approach
- Application-supplied acceptor creates, registers
handlers - A factory
- Single-threaded
- A handler at a time
- Concurrency
- Good with small jobs (e.g., TCP/IP stream
fragments) - With large jobs?
From http//www.cs.wustl.edu/schmidt/PDF/proactor
.pdf
11A Second Approach Multi-Threaded
- Acceptor spawns, e.g., a thread-per-connection
- Instead of registering handler with a reactor
- Handlers are active
- Multi-threaded
- Highly concurrent
- May be physically parallel
- Concurrency hazards
- Any shared resources between handlers
- Locking / blocking costs
From http//www.cs.wustl.edu/schmidt/PDF/proactor
.pdf
12A Third Approach Proactive
- Acceptor/handler
- registers itself with OS, not with a separate
dispatcher - Acts as a completion dispatcher itself
- OS performs work
- E.g., accepts connection
- E.g., reads a file
- E.g., writes a file
- OS tells completion dispatcher its done
- Accepting connect
- Performing I/O
From http//www.cs.wustl.edu/schmidt/PDF/proactor
.pdf
13Proactor Dynamics
Asynch Operation Processor
Asynch Operation
Completion Dispatcher
Completion Handler
Application
Asynch operation initiated
invoke
execute
Operation runs asynchronously
Operation completes
dispatch
handle_event
Completion handler notified
Completion handler runs
From http//www.cs.wustl.edu/schmidt/PDF/proactor
.pdf
14Asynch I/O Factory classes
- ACE_Asynch_Read_Stream
- Initialization prior to initiating read open()
- Initiate asynchronous read read()
- (Attempt to) halt outstanding read cancel()
- ACE_Asynch_Write_Stream
- Initialization prior to initiating write open()
- Initiate asynchronous write write()
- (Attempt to) halt outstanding write cancel()
15Asynchronous Event Handler Interface
- ACE_Handler
- Proactive handler
- Distinct from reactive ACE_Event_Handler
- Return handle for underlying stream
- handle()
- Read completion hook
- handle_read_stream()
- Write completion hook
- handle_write_stream()
- Timer expiration hook
- handle_time_out()
16Proactor Interface (CNPV2 Section 8.5)
- Lifecycle Management
- Initialize proactor instance ACE_Proactor(),
open () - Shut down proactor ACE_Proactor(), close()
- Singleton accessor instance()
- Event Loop Management
- Event loop step handle_events()
- Event loop proactor_run_event_loop()
- Shut down event loop proactor_end_event_loop()
- Event loop completion proactor_event_loop_done()
- Timer Management
- Start/stop timers schedule_timer(),
cancel_timer() - I/O Operation Facilitation
- Input create_asynch_read_stream()
- Output create_asynch_write_stream()
17Proactor Consequences
- Benefits
- Separation of application, concurrency concerns
- Potential portability, performance increases
- Encapsulated concurrency mechanisms
- Separate lanes, no inherent need for
synchronization - Separation of threading and concurrency policies
- Liabilities
- Difficult to debug
- Opaque and non-portable completion dispatching
- Controlling outstanding operations
- Ordering, correct cancellation notoriously
difficult