To secure processes from entering sleep, we need to keep in mind two rules:
1. Never sleep in the atomic context.
2. Do not know the environment after the process is sleep. After waking up, you must check again to make sure that the conditions we are waiting for are true.
The test example only targets sleep functions. The example itself is meaningless. In the test example, sleep during reading until the conditions are met, and then wake up a process waiting for reading when writing again if any process is reading.
Static declare_wait_queue_head (hwait); static unsigned state = 0; ssize_t fileops_read (struct file * filp, char _ User * buff, size_t count, loff_t * OFFP) {printk (kern_alert "process % I (% s) Wait for read \ n", current-> PID, current-> comm); // wait_event (hwait, state! = 0);/* the process will be placed in non-interrupted sleep */wait_event_interruptible (hwait, state! = 0);/* the process can be interrupted by a signal to sleep. If a non-0 value is returned, the process is interrupted by a signal. * // * the waiting period is jiffy. If a condition is met, 0 is returned, the process cannot be interrupted * // wait_event_timeout (hwait, state! = * Hz); // wait for 10 seconds for non-interrupted sleep, return 0 for time-out, return the remaining jiffies for success, and * return the remaining jiffies for time-out. If the condition is met, return 0, the process can be interrupted by signals * // wait_event_interruptible_timeout (hwait, state! = * Hz); // wait for 10 seconds for the interrupted sleep, return 0 for timeout, return the remaining jiffies for success, and return-erestartsys state = 0 for the interrupted sleep; printk (kern_alert "process % I (% s) awke up \ n", current-> PID, current-> comm); Return 0;} ssize_t fileops_write (struct file * filp, const char _ User * buff, size_t count, loff_t * OFFP) {/* The system call will always write until the write count is sufficient. If the return value is less than count, this method will be called again until an error is returned or count */printk (kern_alert "process % I (% s) Wake up all \ n", current-> PID, current-> comm); State = 1; wake_up_interruptible (& hwait); // note that non-interrupted sleep is unavailable. This function should use wake_up return count ;}
Test Results
Open multiple terminals and read the device [root @ localhost ctest] # Cat/dev/moduledev60 then open a device and write data to it [root @ localhost ctest] # echo 111>/dev/ moduledev60 has a terminal Cat return every time it is written, of course, no data is printed here.