Information Technology Reference
In-Depth Information
//Event-driven
Hashtable<Buffer*>*hash;
while(1){
connection=useselect()tofinda
readableconnectionID
buffer=hash.remove(connection);
got=read(connection,tmpBuf,TMP_SIZE);
buffer->append(tmpBuf,got);
buffer=hash.put(connection,buffer);
//Thread-per-client
Buffer*b;
while(1){
got=read(connection,tmpBuf,TMP_SIZE);
buffer->append(tmpBuf,got);
}
}
When these programs execute, the system does essentially the same things.
However, in the first case, it explicitly saves and restores each connection's
state, while in the second case, the thread system saves and restores this
state transparently.
The state in both cases is also essentially the same. In both cases, the ap-
plication needs to keep one buffer per client connection. In the event-driven
case, the application maintains a data structure (e.g., hash in the pseudocode)
to keep track of the different clients' data structures. In the thread-per-client
case, each thread has just one buffer to keep track of, and the operating sys-
tem keeps track of the different threads' states.
thread 1's
stack
thread 2's
stack
thread 3's
stack
Hash Table
buf1
thread 1's
stack
buf2
buf1
buf2
buf3
buf3
conn 1
waiting
list
conn 2
waiting
list
conn 3
waiting
list
select()
waiting
list
TCB1
TCB2
TCB3
TCB1
To compare the event-driven and threads approaches, consider the three
goals for threads discussed at the start of this chapter.
Performance: Coping with high-latency I/O devices. Either approach|
event-driven or threads|can be used to overlap I/O and processing. Which
provides better performance?
In the past, the common wisdom has been that the event-driven approach
could often be significantly faster for two reasons. First, the space and
context switch overheads of the approach can be lower because a thread
system must use generic code that allocates a stack for each thread's state
and that saves and restores all registers on each context switch, but the
event-driven approach allows programmers to allocate and save/restore
just the state needed for each thread. Second, some past operating sys-
tems had inecient or unscalable implementations of their thread systems,
making it important not to create too many threads for each process.
Today, the comparison is less clear cut. Many systems now have large
memories, so the cost of allocating a thread stack for each task is less
 
Search WWH ::




Custom Search