Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   I/O Request Priorities

In Chapter 26, “Thread Basics,” I showed how setting thread priorities affects how threads are sched- uled. However, threads also perform I/O requests to read and write data from various hardware devices. If a low-priority thread gets CPU time, it could easily queue hundreds or thousands of I/O requests in a very short time. Because I/O requests typically require time to process, it is possible that a low-priority thread could significantly affect the responsiveness of the system by suspending high-priority threads, which prevents them from getting their work done. Because of this, you can see a machine become less responsive when executing long-running low-priority services such as disk defragmenters, virus scanners, content indexers, and so on.13

Windows allows a thread to specify a priority when making I/O requests. For more details about I/O priorities, refer to the white paper at http://www.microsoft.com/whdc/driver/priorityio.mspx.

Unfortunately, the FCL does not include this functionality yet; hopefully, it will be added in a future version. However, you can still take advantage of this feature by P/Invoking out to native Win32 func- tions. Here is the P/Invoke code.

 

internal static class ThreadIO {

public static BackgroundProcessingDisposer BeginBackgroundProcessing( Boolean process = false) {

 

ChangeBackgroundProcessing(process, true);

return new BackgroundProcessingDisposer(process);

}

 

public static void EndBackgroundProcessing(Boolean process = false) { ChangeBackgroundProcessing(process, false);

}

 

private static void ChangeBackgroundProcessing(Boolean process, Boolean start) { Boolean ok = process

? SetPriorityClass(GetCurrentWin32ProcessHandle(),

start ? ProcessBackgroundMode.Start : ProcessBackgroundMode.End)

: SetThreadPriority(GetCurrentWin32ThreadHandle(),

start ? ThreadBackgroundgMode.Start : ThreadBackgroundgMode.End); if (!ok) throw new Win32Exception();

}

 

// This struct lets C#'s using statement end the background processing mode public struct BackgroundProcessingDisposer : IDisposable {

private readonly Boolean m_process;

public BackgroundProcessingDisposer(Boolean process) { m_process = process; } public void Dispose() { EndBackgroundProcessing(m_process); }

}

 

 
 

13 The Windows SuperFetch feature takes advantage of low-priority I/O requests.


// See Win32’s THREAD_MODE_BACKGROUND_BEGIN and THREAD_MODE_BACKGROUND_END

private enum ThreadBackgroundgMode { Start = 0x10000, End = 0x20000 }

 

// See Win32’s PROCESS_MODE_BACKGROUND_BEGIN and PROCESS_MODE_BACKGROUND_END

private enum ProcessBackgroundMode { Start = 0x100000, End = 0x200000 }

 

[DllImport("Kernel32", EntryPoint = "GetCurrentProcess", ExactSpelling = true)] private static extern SafeWaitHandle GetCurrentWin32ProcessHandle();

 

[DllImport("Kernel32", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]



private static extern Boolean SetPriorityClass( SafeWaitHandle hprocess, ProcessBackgroundMode mode);

 

[DllImport("Kernel32", EntryPoint = "GetCurrentThread", ExactSpelling = true)] private static extern SafeWaitHandle GetCurrentWin32ThreadHandle();

 

[DllImport("Kernel32", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]



private static extern Boolean SetThreadPriority( SafeWaitHandle hthread, ThreadBackgroundgMode mode);

 

// http://msdn.microsoft.com/en­us/library/aa480216.aspx

[DllImport("Kernel32", SetLastError = true, EntryPoint = "CancelSynchronousIo")] [return: MarshalAs(UnmanagedType.Bool)]

private static extern Boolean CancelSynchronousIO(SafeWaitHandle hThread);

}

 

And here is code showing how to use it.

 

public static void Main () {

using (ThreadIO.BeginBackgroundProcessing()) {

// Issue low­priority I/O requests in here (eg: calls to ReadAsync/WriteAsync)

}

}

 

You tell Windows that you want your thread to issue low-priority I/O requests by calling Thread­ IO’s BeginBackgroundProcessing method. Note that this also lowers the CPU scheduling priority of the thread. You can return the thread to making normal-priority I/O requests (and normal CPU scheduling priority) by calling EndBackgroundProcessing or by calling Dispose on the value returned by BeginBackgroundProcessing (as shown in the preceding code via C#’s using state- ment). A thread can only affect its own background processing mode; Windows doesn’t allow a thread to change the background processing mode of another thread.

If you want all threads in a process to make low-priority I/O requests and have low CPU schedul- ing, you can call BeginBackgroundProcessing, passing in true for the process parameter. A process can only affect its own background processing mode; Windows doesn’t allow a thread to change the background processing mode of another process.



C HA P T E R 2 9


Date: 2016-03-03; view: 828


<== previous page | next page ==>
Nbsp;   Some I/O Operations Must Be Done Synchronously | Primitive Thread Synchronization Constructs
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.006 sec.)