If an application handles multiple devices, such as applications that read network data, keys, and serial ports, there are three ways to think about it:
Method 1:
Serial + blocked mode reads:
while (1) {
Read (standard input);
Read (network);
}
Disadvantage: Whenever blocking reads the standard input, if the user does not perform the standard input operation, and the client sends the data to the server, the server cannot read the data sent by the client!
Method 2:
Use multi-threaded or multi-process mechanism to achieve read:
Open up multiple threads, each of which processes a device, does not cause the data to be unreadable, but the overhead of the system is larger than the method 1!
Scenario 3: Processing mechanisms for advanced IO provided by Linux systems
Select/poll: Like both, the master process can use Select or poll to listen to multiple devices!
Its principle seems to be: Method 1 is equivalent to have a security, look at 10 houses, if the thief came in from the tenth household began to steal, security but from the first household check.
Method 2 is equivalent to employing 10 security guards, with a large overhead
Method 3 is equivalent to buy 10 sets of surveillance equipment, a security Watch surveillance video, a situation alarm
************************************************************************************
Select function Prototypes:
int select (int Nfds,
Fd_set *readfds,
Fd_set *writefds,
Fd_set *exceptfds,
struct Timeval *timeout);
function function:
The main process can use this function to listen to multiple devices, once it is found that the listening device is not available (unreadable, not writable, and no exception), then the main process into hibernation, once the listening device, as long as there is a device available (readable or writable or abnormal) will wake up the dormant main process, Select will also return.
Note that this function only plays a listening function, and the subsequent processing of the data, such as reading and writing, is done through READ,WRITE,IOCTL!
Parameter description:
Nfds:
Access to the device is always first open to obtain FD;
Monitor the device, the largest file descriptor fd+1;
Data type Fd_set: A collection of file descriptors used to hold the device that describes the listener, which is the file descriptor of the listening device, and if select is to listen to a device, the FD of the device must be added to the corresponding file descriptor collection!
Readfds: Read the file descriptor collection pointer, if select to listen to the device is readable, you need to add the device's FD to this collection!
Writefds: Write the file descriptor set pointer, if select to listen to the device is writable, you need to add the device's FD to this collection!
Exceptfds: Exception file descriptor set pointer, if select to listen to the device if there is an exception, you need to add the device's FD to this collection!
Note: FD for one device can be added to three sets at the same time!
Timeout: Specifies the time-out for the listener, if this parameter specifies a time, such as 5 seconds, select discovers that the device is not available, the main process goes into hibernation, if the device is not available within 5 seconds, 5 seconds expires, the main process actively wakes up, and if this parameter is specified as NULL, hibernation is permanent!
Return value: There are three kinds
If equals 0: indicates a timeout;
If less than 0: indicates a system error;
If greater than 0: Indicates that the device is available (at least one device, or all);
Method for file Descriptor collection operations:
Fd_set RfDs; Defines a collection of read file descriptors
Unblock the FD device from the collection
void fd_clr (int FD, fd_set *set);
Determines whether the wake of the main process caused by the device FD, or False if True is returned
int fd_isset (int FD, fd_set *set);
Add a new device to be monitored
void Fd_set (int FD, fd_set *set);
Emptying the file Descriptor collection
void Fd_zero (Fd_set *set);
Note: If you want to listen again, you need to empty the collection again and add a listening device!
***********************************************************************************
These are function calls at the application level
At the kernel level:
Hibernate in Sys_select, poll do not cause sleep
Select System Call Procedure:
1. The application invokes select, first invoking the C library's Select function implementation;
The select of the 2.C library saves the select system call number to the R7 register, calling the SVC (the new
) or SWI (old) triggers a soft interrupt, where the user space is trapped in the kernel space, ARM
Mode of operation is changed from user mode to SVC management mode;
3. Jump to the entry address of the kernel Ready exception vector table, according to the R7 saved system tune
Use the number to find the corresponding implementation function in the system call table as an index Sys_select
4.sys_select to complete:
1. Call the poll function that corresponds to the driver for the device being monitored.
When the devices being monitored are not available, their driver's poll function returns 0;
2. Determine whether the drive is active wake-up, or timeout, or receive a wake-up signal;
3. If there is no driver active wakeup, there is no timeout to wake up, no signal received,
Sys_select Call Poll_schedule_timeout actively let the process into hibernation;
4. Assume that a device that is being monitored is available (readable or writable or abnormal
, the hardware can be judged by interrupts), which wakes up the dormant main process;
5.sys_select's Poll_schedule_timeout function returns, no longer sleeps
6. Once again, the poll function driven by the monitored device is called one at a time, which is available
Device corresponding to the driver poll function will return non 0;
7.if (ret | | time_out | | ...)//ret = 1, return immediately to user empty
, the return value is RET value
Summarize:
1. Make clear that the poll function, which should be driven at the bottom, uses the wait queue mechanism to hibernate the process
But waiting for the queue to hibernate 9 steps is not all driven by the poll to write, there is part of the inside
Nuclear sys_select to achieve;
2. Drive the poll function to complete the following:
1. Call poll_wait to add the current process to the driver-defined wait queue header
2. Depending on whether the device is available, decide to return 0 or not 0
3. Clear: Monitoring mechanism, the underlying poll function is not necessary, if you want to listen to the device can also
The use of multithreading can also be done to monitor, but if you want to use the Select/poll
Listen to the device, the driver must have poll implementation!
is a simple implementation of Sys_select:
Through the analysis of kernel code, the real sleep implementation is implemented in the kernel.
The Schedule_hrtimeout_range_clock function in the Poll_schedule_timeout function is implemented in the Schedule_hrtimeout_range
is not implemented in the poll function.
Monitor multiple devices with Select/poll