Multithreading: I/O and the thread pool

Published Thu, Jun 4 2009 14:10

When we started looking at how we could use the thread pool for asynchronous work, I (only!) mentioned three options:

  • use the pool to run a task when IO completes;
  • run a (possible recurrent) task at a specific time;
  • execute a task when a kernel object is signaled.

There is still another option: you can also rely on the thread pool’s I/O completion support and write code that runs a callback – aka completion callback - on a thread from the pool in response to the end of an asynchronous I/O operation.

The CLR pool maintains a single I/O completion port per process. I/O completion ports were introduced in windows to improve scalability. The docs say that “I/O completion ports provide an efficient threading model for processing multiple asynchronous I/O requests on a multiprocessor system”. Even though I/O ports are a powerful concept, in managed code you’ll probably use them for supporting asynchronous I/O.

Let’s concentrate on files (I believe this is the most common case)…The idea is the following: you start by opening a file for an asynchronous operation and bind the handle of that file to the process wide completion port (notice that you can bind several handles to the same completion port). After doing that, you can simply start the required asynchronous operation and keep doing other interesting things (since you’ve started an asynchronous operation, the thread from where you started the async read or write won’t block).

Whenever that operation completes, it will queue a packet on that I/O completion port. The port will then proceed and use one of the thread pool’s thread to run the callback you’ve specified. The greatest advantage of using the thread pool for doing this kind of thing is that it already manages its own completion port and you don’t have to worry about the creating the “correct” number of threads that should be waiting on the port for the completion packets (ie, you’re free of having to manage the port itself and the threads that wait on it – not sure on what you think, but it does sound good to me :) ).

Even though you can write the “low-level” code for doing this kind of stuff on managed code (notice the irony of calling this interaction “low-level” code), the truth is that in most scenarios you’ll end up using the asynchronous IO APIs introduced on the .NET framework since they’re integrated with the pool.

Anyway, it would be probably a good idea to take a look at same code before using the high level version calls. Fortunately for me, someone else has already posted some demo code online and this means that I will simply redirect you to that interesting post.

And I guess it’s all for now. Keep tuned for more on multithreaded applications.

Filed under: ,

Comments

# 9eFish said on Thursday, June 04, 2009 8:46 PM

9efish.感谢你的文章 - Trackback from 9eFish

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above:  

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover