当前位置:首页 » 软件开发
开发技术指南» 文章正文
    引言: IOCP Thread Pooling in C#By Will
 

 

    摘要:在项目开发的过程当中,项目组开发成员的编程风格差异和数据库操作语句sql的灵活性给项目组带来了越来越多的操作和维护难度。 比如: 从user表中取出所有数据,有的人会写成 ’ select * from user’ ,有的人会写成 ‘select all from user’,虽然在操作中不会有任何的错误,但在其他人读程序的过程时就会产生不好的感觉。 如果这种程序差异在项目中的数量级很多,那......
 · [原创]c#冒泡算法!     »显示摘要«
    摘要:参加多次笔试,居然有几次都考到了冒泡算法,一次是c#版的填空,一次是javascript版的全部写出。虽然每次都凭着我对冒泡法的理解给弄出来的,但是多多少少与标准模式有点差别,在网上搜了一下关于c#版的冒泡算法,居然也没有一个象样的,自己对照算法模式认真写了一个c#版的,已经测试成功。同时附上public void bubblesort(int[] r){ int i,j,temp; //交换标志......


[收藏]IOCP Thread Pooling in C#
上一页   ...the remaining scope of this article will show you how to add iocp thread pools to your c# server based applications.  how to configure the thread pools for your specific application will not be covered.  it is suggested to use the general rules as discussed.

【程序编程相关:为您的应用程序加上注册的限制

  【推荐阅读:[dotNET]如何利用Configur

  【扩展信息:Using ASP.NET Sessio

system requirements

a basic understanding of c# is required to follow through the examples and the classes.  basic concepts of type, properties, threading, synchronization, and delegates are required.

defining the problem

 

iocp thread support has not been made available to c# developers through the “system.threading” namespace.  we need to access the win32 api calls from the kernel32.dll.  this requires us to write unsafe code.  this is really not a problem, but something that needs to be discussed.  let’s take a look at the win32 api calls we need to implement an iocp thread pool.

 

[dllimport("kernel32", charset=charset.auto)]

private unsafe static extern uint32 createiocompletionport(uint32 hfile, uint32 hexistingcompletionport, uint32* puicompletionkey, uint32 uinumberofconcurrentthreads);

 

this win32 api call is used to create an iocp thread pool.  the first argument will always be set to invalid_handle_value, which is 0xffffffff.  this tells the operating system this iocp thread pool is not linked to a device.  the second argument will always be set to 0.  there is no existing iocp thread pool because we are creating this for the first time.  the third argument will always be null.  we do not require a key because we have not associated this iocp thread pool with a device.  the last argument is the important argument.  here we define the concurrency level of the thread pool.  if we pass a 0 for this argument the operating system will set the concurrency level to match the number of cpu’s in the machine.  this option gives us our best chance to be scalable and take advantage of the number of cpu’s present in the machine.  this api call will return a handle to the newly created iocp thread pool.  if the api call fails, it will return null.

 

[dllimport("kernel32", charset=charset.auto)]

private unsafe static extern boolean closehandle(uint32 hobject);

 

this win32 api call is used to close our thread pool.  the only argument is the handle to the iocp thread pool.  this api call will return true or false if the handle can not be closed.

 

[dllimport("kernel32", charset=charset.auto)]

private unsafe static extern boolean postqueuedcompletionstatus(uint32 hcompletionport, uint32 uisizeofargument, uint32* puiuserarg, overlapped* poverlapped);

 

this win32 api call is used to post work in the iocp thread pool queue.  other threads in our application will make this win32 api call.  the first argument is the handle to the iocp thread pool.  the second argument is the size of the data we are posting to the queue.  the third argument is a value or a reference to an object or data structure we are posting to the queue.  the last argument will always be null.  the following diagram shows how the data is associated with the posted work.

 

 

in diagram e, we have two threads actively processing posted work and one piece of work on the queue waiting for its data to be processed.  the thing to note here is that each piece of work was given a reference to its specific data.  i am calling this variable pdata to help describe what is happening in the iocp thread pool.  the actual name or structure of this variable is undocumented.

 

when we make this api call in a c++ application, we can pass the address of any object in memory we wish, as in diagram e.  in c#, we don’t have the same luxury because of the managed heap.  the managed heap is a contiguous region of address space that contains all of the memory allocated for reference variables.  the heap maintains a pointer that indicates where the next object is to be allocated, and all allocations are contiguous from that point.  this is much different from the c-runtime heap. 

 

the c-runtime heap uses a link list of data structures to reference available memory blocks.  for the c-runtime heap to allocate memory, it must walk through the link list until a large enough block of free memory is found.  then the free block of memory must be resized, and the link list adjusted.  if objects are allocated consecutively in a c++ application, those objects could be allocated anywhere on the heap.  this can never happen with the managed heap.  objects that are allocated consecutively in a c# application will always be allocated consecutively on the managed heap.  the catch is that the managed heap must be compacted to guarantee the heap does not run out of memory.  that is the job of garbage collection.

 

for more information on garbage collection, try these links:

asp?url=/library/en-us/cpguide/html/cpconautomaticmemorymanagement.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconautomaticmemorymanagement.asp

aspx">http://msdn.microsoft.com/msdnmag/issues/1100/gci/default.aspx

aspx">http://msdn.microsoft.com/msdnmag/issues/1200/gci2/default.aspx

 

in diagram f, we have allocated four objects on the managed heap.  imagine that the managed heap has allocated memory for these objects at address fdeo, fddo, fdco, and fdbo.  this would mean the value of pclass1 is fdeo, the value of pclass2 is fddo, the value of pclass3 is fdco, and the value of pclass4 is fdbo. 

 

myclass pclass1 = new myclass();

myclass pclass2 = new myclass();

myclass pclass3 = new myclass();

myclass pclass4 = new myclass();

now we write the following code.

 

pclass2 = null;

 

diagram g shows what happens to the managed heap after garbage collection takes place and the managed heap is compacted.

 

 

the class 2 object has been removed from the managed heap and the class3 and class 4 objects have been moved.  now the value of pclass3 is fddo and the value of pclass4 is fdco.  the value that the pointer points to has changed.  the garbage collection process changes the values of all reference variables to make sure they are pointing to the correct objects after the managed heap is compacted.

 

so what does this mean for our iocp thread pool implementation?  if we pass the reference of a managed object as the data for the work, there is a chance the reference is no longer valid when a thread in the pool is chosen to work on the data.

 

 

in diagram h, we have passed a reference to the class 3 object as the data for the work posted to the iocp thread pool.  this object is at address fdco.  before the work is given to thread 1, the class 2 object is marked for deletion.  then the garbage collection process runs, and the managed heap is compacted.  now in diagram i, the work has been given to thread 1 for processing.  the value of pdata is still fdco, but class 3 is no longer at address fdco, it is at address fddo.  the thread will perform the work, but using class 4 instead of class 3.

 


...   下一页
 ·分享:project级别的权限控制     »显示摘要«
    摘要:在项目中常常要定义不同的project级别的用户和权限,仿照windows的role/user/access right的控制,我的实现如下:1、在数据库中建立5个表:tsvrole, tsvuser, tsvobject, tsvroleuser和tsvroleobject,分别存储role、user、object、role-user对应关系以及role-object对应关系。建表的tsql如下......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE