Download presentation
Presentation is loading. Please wait.
1
Multiplexing i/o A look at some alternatives under Linux for dealing concurrently with multiple sources of device-input
2
What’s the problem? Some applications need to process input from more than one peripheral device Input is normally obtained using a ‘read()’ operation on an open file-descriptor But ‘read()’ may cause a process to sleep if no data is ready from a particular device While asleep the process is unable to read new data that is ready on any other device
3
Alternative approaches There are at least five possible ways for overcoming this problem of ‘deadlock’ All of these approaches have been used, but some have worked better than others Four of these alternatives are supported by the standard features of UNIX systems (The fifth approach, while very interesting, seems to be unique to the Mach system)
4
One immediate application We proposed the idea of a Linux program that would utilize our recent knowledge of how to program RealTek’s 8139 network controllers in our classroom’s workstations We want any pair of users who are sitting at different computers to be able to ‘chat’ by typing messages in a window that will be visible remotely in a different window This requires multiplexed input (Project 2)
5
Method 1: timesharing Any UNIX application can fork a number of child processes, each dedicated to reading data from just one of the open device-files The operating system’s scheduler will then give each process its opportunity to read and process any new data that becomes available from its particular device-file But scheduling consumes CPU time, and any task-coordination can add complexity
6
Method 2: non-blocking i/o UNIX applications can open device-files in a ‘non-blocking’ mode (if the driver allows) Instead of sleeping when no data is ready, a process can proceed immediately to try reading from one of the other device-files But this produces a ‘CPU-bound’ program that can ‘starve’ other system applications (by constantly calling ‘read()’ for no data)
7
Method 3: using signals UNIX programs can install signal-handlers Then the application can ‘sleep’ until it is woken up by a signal that indicates new data can be read from a specific device Indeed this approach is widely used -- in cases where the underlying device-driver implements the required support-routines for so-called ‘asynchronous’ input-output
8
Method 4: using ‘select()’ UNIX programs can invoke a convenient library-function, called ‘select()’, which lets the process ‘sleep’ until at least one of the device-files of interest is ready for reading new data (or for writing new data), or until a predetermined ‘timeout’ has expired This approach is favored because it enjoys even greater efficiency and flexibility, not to mention simplicity, than using ‘signals’
9
Method 5: multiplexed-read This method is the most efficient of all, as it needs only one system-call, in ‘blocking mode’, to be sure of obtaining new data from at least one device in a specified set Its programming syntax is not (yet) part of the POSIX (Portable Operating Systems) standard; it’s not implemented in Linux
10
Using Method 4 To support use of the ‘select()’ function, a character-mode device-driver needs only to implement a ‘poll()’ driver-method It is very straightforward to do this: review Chapter 6 of “Linux Device Drivers (3Ed)” We do it for our RealTek driver ‘withpoll.c’ Our ‘trychat.cpp’ demo-program uses the services of this ‘withpoll.c’ device-driver
11
The ‘fd_set’ object Header-file: #include Declare:fd_setreadset; Initialize:FD_ZERO( &readset ); Setup for use:FD_SET( nic, &readset ); FD_SET( kb, &readset ); Use: int m = 1 + ( ( kb < nic ) ? nic : kb; if ( select( m, &readset, 0, 0, 0 ) < 0 ) break; if ( FD_ISSET( kb, &readset ) read_kb(); if ( FD_ISSET( nic, &readset ) read_nic();
12
In-class exercise Try your hand at implementing Method 1 (the timeshare method) for a version of ‘nicchat.cpp’ that does not require ‘poll()’ You can use our earlier ‘rxplustx.c’ driver You can replace the ‘select()’ function-call with a ‘fork()’ function-call, letting the child- process read from standard-input while the parent-process reads from ‘/dev/nic’.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.