<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_轨迹2003</title><subtitle type="text">做自己该做的事,做自己想做的事!</subtitle><id>http://feed.cnblogs.com/blog/u/39456/rss</id><updated>2011-10-14T14:36:26Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/39456/rss"/><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180149.html</id><title type="text">Linux虚拟内存</title><summary type="text">当你运行一个程序，程序中有许多东西需要存储，堆、栈以及各种功能库。而这一切在你写程序时可能都不需要自己控制，Linux内核会帮你完成这些存储的调度，你只需要告诉它你需要做什么，内核就会在合适的地方给你分配内存空间。本文主要通过几个实例程序的内存使用研究，来为大家展示Linux的内存使用状况。第一个例子：下面一段程序会打印出程序的pid（进程号）后挂起。</summary><published>2011-09-18T02:05:00Z</published><updated>2011-09-18T02:05:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180149.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180149.html"/><content type="html">&lt;p&gt;当你运行一个程序，程序中有许多东西需要存储，堆、栈以及各种功能库。而这一切在你写程序时可能都不需要自己控制，Linux内核会帮你完成这些存储的调度，你只需要告诉它你需要做什么，内核就会在合适的地方给你分配内存空间。本文主要通过几个实例程序的内存使用研究，来为大家展示Linux的内存使用状况。&lt;/p&gt;&#xD;
&lt;p&gt;第一个例子：下面一段程序会打印出程序的pid（进程号）后挂起。&lt;/p&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&#xD;
#include &amp;lt;unistd.h&amp;gt;&#xD;
#include &amp;lt;sys/types.h&amp;gt;&#xD;
&#xD;
int main() {&#xD;
  printf("run `pmap %d`\n", getpid());&#xD;
  pause();&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;将上面代码保存成文件 mem_munch.c 然后运行下面程序编译并执行：&lt;/p&gt;&lt;pre&gt;$ gcc mem_munch.c -o mem_munch&#xD;
$ ./mem_munch&#xD;
run `pmap 25681`&lt;/pre&gt;&#xD;
&lt;p&gt;上面进程号是25681，可能你试验的结果会不太一样。&lt;/p&gt;&#xD;
&lt;p&gt;下面我们通过pmap命令来查看一下这个小程序的内存使用情况&lt;/p&gt;&lt;pre&gt;$ pmap 25681&#xD;
25681:   ./mem_munch&#xD;
0000000000400000      4K r-x--  /home/user/mem_munch&#xD;
0000000000600000      4K r----  /home/user/mem_munch&#xD;
0000000000601000      4K rw---  /home/user/mem_munch&#xD;
00007fcf5af88000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fcf5b112000   2044K -----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fcf5b311000     16K r----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fcf5b315000      4K rw---  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fcf5b316000     24K rw---    [ anon ]&#xD;
00007fcf5b31c000    132K r-x--  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007fcf5b512000     12K rw---    [ anon ]&#xD;
00007fcf5b539000     12K rw---    [ anon ]&#xD;
00007fcf5b53c000      4K r----  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007fcf5b53d000      8K rw---  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007fff7efd8000    132K rw---    [ stack ]&#xD;
00007fff7efff000      4K r-x--    [ anon ]&#xD;
ffffffffff600000      4K r-x--    [ anon ]&#xD;
 total             3984K&lt;/pre&gt;&#xD;
&lt;p&gt;上面的结果是这个程序的内存使用情况，其实更确切的说是这个程序认为它使用内存的情况。从上面的结果我们能看到，当你访问libc库时，实际上是对内存地址00007fcf5af88000的访问，当你访问ld库时，实际上是对内存地址00007fcf5b31c000的访问。&lt;/p&gt;&#xD;
&lt;p&gt;上面的输出可能还比较抽象，下面我们修改一下上面的程序，我们在程序的堆和栈上各放一块数据。&lt;/p&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&#xD;
#include &amp;lt;unistd.h&amp;gt;&#xD;
#include &amp;lt;sys/types.h&amp;gt;&#xD;
#include &amp;lt;stdlib.h&amp;gt;&#xD;
&#xD;
int main() {&#xD;
  int on_stack, *on_heap;&#xD;
&#xD;
  //局部变量是放在栈上的，所以 on_stack 的地址就是栈的初始地址&#xD;
  on_stack = 42;&#xD;
  printf("stack address: %p\n", &amp;amp;on_stack);&#xD;
&#xD;
  //malloc 的内存是在堆上分配的&#xD;
  on_heap = (int*)malloc(sizeof(int));&#xD;
  printf("heap address: %p\n", on_heap);&#xD;
&#xD;
  printf("run `pmap %d`\n", getpid());&#xD;
  pause();&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;编译运行：&lt;/p&gt;&lt;pre&gt;$ ./mem_munch&#xD;
&lt;span style="color: #008000"&gt;stack address: 0x7fff497670bc&lt;/span&gt;&#xD;
&lt;span style="color: #ff0000"&gt;heap address: 0x1b84010&lt;/span&gt;&#xD;
run `pmap 11972`&lt;/pre&gt;&#xD;
&lt;p&gt;然后再用pmap命令查看一下内存使用：&lt;/p&gt;&lt;pre&gt;$ pmap 11972&#xD;
11972:   ./mem_munch&#xD;
0000000000400000      4K r-x--  /home/user/mem_munch&#xD;
0000000000600000      4K r----  /home/user/mem_munch&#xD;
0000000000601000      4K rw---  /home/user/mem_munch&#xD;
&lt;span style="color: #008000"&gt;&lt;span style="color: #ff0000"&gt;0000000001b84000    132K rw---    [ anon ]&lt;/span&gt;&#xD;
&lt;/span&gt;00007f3ec4d98000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007f3ec4f22000   2044K -----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007f3ec5121000     16K r----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007f3ec5125000      4K rw---  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007f3ec5126000     24K rw---    [ anon ]&#xD;
00007f3ec512c000    132K r-x--  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007f3ec5322000     12K rw---    [ anon ]&#xD;
00007f3ec5349000     12K rw---    [ anon ]&#xD;
00007f3ec534c000      4K r----  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007f3ec534d000      8K rw---  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
&lt;span style="color: #008000"&gt;00007fff49747000    132K rw---    [ stack ]&lt;/span&gt;&#xD;
00007fff497bb000      4K r-x--    [ anon ]&#xD;
ffffffffff600000      4K r-x--    [ anon ]&#xD;
 total             4116K&lt;/pre&gt;&#xD;
&lt;p&gt;这次多出了上面红色的一行内容，红色内容就是堆的起始位置：&lt;/p&gt;&lt;pre&gt;0000000001b84000    132K rw---    [ anon ]&lt;/pre&gt;&#xD;
&lt;p&gt;在我们程序运行的输出里也有一行红色的输出，这是这个地址在程序中的内存地址：&lt;/p&gt;&lt;pre&gt;heap address: 0x1b84010&lt;/pre&gt;&#xD;
&lt;p&gt;这两个地址基本上是一样的，其中的anon是Anonymous的缩写，表明这段内存是没有文件映射的。&lt;/p&gt;&#xD;
&lt;p&gt;我们再看上面绿色的两行，与上面相对应，这两行分别是用pmap 和应用程序看到的栈起始地址：&lt;/p&gt;&lt;pre&gt;00007fff49747000    132K rw---    [ stack ]&lt;/pre&gt;&lt;pre&gt;stack address: 0x7fff497670bc&lt;/pre&gt;&#xD;
&lt;p sizcache="1" sizset="50"&gt;上面说到的内存使用，都只是程序认为自己对内存的使用，实际上程序在分配内存是不知道系统内存的状态的。所以上面的输出都只是从程序自己的角度看到的内存使用状况。比如在上面的例子中，我们看到程序的内存地址空间是从0&amp;#215;0000000000400000到0xffffffffff600000的所有地址（而0xffffffffff600000到0&amp;#215;00007fffffffffffffff之间的地址是有&lt;a href="http://en.wikipedia.org/wiki/X86-64#Canonical_form_addresses" target="_blank"&gt;特殊用处&lt;/a&gt;的，这里不多讲）。这样算下来，我们总共可以使用的内存空间有1千万TB。&lt;/p&gt;&#xD;
&lt;p sizcache="1" sizset="51"&gt;但是实际上目前没有硬件能有1千万TB的物理内存。为什么操作系统会如此设计呢？原因有很多，可以看&lt;a href="http://en.wikipedia.org/wiki/Virtual_memory" target="_blank"&gt;这里&lt;/a&gt;，但也正因此，我们可以使用远远超出物理内存大小的内存空间。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;内存映射&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;内存映射的原理就是让操作系统将一个文件映射到一段内存中，然后在操作这个文件内存就可以像操作内存一样。比如我们创建一个完全内容随机的文件，然后将它用内存映射的方式映射到一段内存空间中。那么我们在这段内存中随便取一位就相当于取到了一个随机数。下面就让我们来做这个实验，先用下面命令生成一个内容随机的文件。&lt;/p&gt;&lt;pre&gt;$ dd if=/dev/urandom bs=1024 count=1000000 of=/home/user/random&#xD;
1000000+0 records in&#xD;
1000000+0 records out&#xD;
1024000000 bytes (1.0 GB) copied, 123.293 s, 8.3 MB/s&#xD;
$ ls -lh random&#xD;
-rw-r--r-- 1 user user 977M 2011-08-29 16:46 random&lt;/pre&gt;&#xD;
&lt;p&gt;然后我们用下面程序来将这个文件内容映射到内存，再从中取出随机数&lt;/p&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&#xD;
#include &amp;lt;unistd.h&amp;gt;&#xD;
#include &amp;lt;sys/types.h&amp;gt;&#xD;
#include &amp;lt;stdlib.h&amp;gt;&#xD;
#include &amp;lt;sys/mman.h&amp;gt;&#xD;
&#xD;
int main() {&#xD;
  char *random_bytes;&#xD;
  FILE *f;&#xD;
  int offset = 0;&#xD;
&#xD;
  // open "random" for reading&#xD;
  f = fopen("/home/user/random", "r");&#xD;
  if (!f) {&#xD;
    perror("couldn't open file");&#xD;
    return -1;&#xD;
  }&#xD;
&#xD;
  // we want to inspect memory before mapping the file&#xD;
  printf("run `pmap %d`, then press ", getpid());&#xD;
  getchar();&#xD;
&#xD;
  random_bytes = mmap(0, 1000000000, PROT_READ, MAP_SHARED, fileno(f), 0);&#xD;
&#xD;
  if (random_bytes == MAP_FAILED) {&#xD;
    perror("error mapping the file");&#xD;
    return -1;&#xD;
  }&#xD;
&#xD;
  while (1) {&#xD;
    printf("random number: %d (press  for next number)", *(int*)(random_bytes+offset));&#xD;
    getchar();&#xD;
&#xD;
    offset += 4;&#xD;
  }&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;然后运行这个程序：&lt;/p&gt;&lt;pre&gt;$ ./mem_munch&#xD;
run `pmap 12727`, then press&lt;/pre&gt;&#xD;
&lt;p&gt;下面我们通过一次次的按下回车键来从这个文件中读取随机数，按下几次后我们可以再通过pmap来查看其内存空间的情况：&lt;/p&gt;&lt;pre&gt;$ pmap 12727&#xD;
12727:   ./mem_munch&#xD;
0000000000400000      4K r-x--  /home/user/mem_munch&#xD;
0000000000600000      4K r----  /home/user/mem_munch&#xD;
0000000000601000      4K rw---  /home/user/mem_munch&#xD;
000000000147d000    132K rw---    [ anon ]&#xD;
&lt;span style="color: #ff0000"&gt;00007fe261c6f000 976564K r--s-  /home/user/random&lt;/span&gt;&#xD;
00007fe29d61c000   1576K r-x--  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fe29d7a6000   2044K -----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fe29d9a5000     16K r----  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fe29d9a9000      4K rw---  /lib/x86_64-linux-gnu/libc-2.13.so&#xD;
00007fe29d9aa000     24K rw---    [ anon ]&#xD;
00007fe29d9b0000    132K r-x--  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007fe29dba6000     12K rw---    [ anon ]&#xD;
00007fe29dbcc000     16K rw---    [ anon ]&#xD;
00007fe29dbd0000      4K r----  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007fe29dbd1000      8K rw---  /lib/x86_64-linux-gnu/ld-2.13.so&#xD;
00007ffff29b2000    132K rw---    [ stack ]&#xD;
00007ffff29de000      4K r-x--    [ anon ]&#xD;
ffffffffff600000      4K r-x--    [ anon ]&#xD;
 total           980684K&lt;/pre&gt;&#xD;
&lt;p&gt;上面的输出和之前的大同小异，但是多出了上面红色的一行。这是我们上面的随机文件映射到内存中的内存。我们再使用pmap -x 选项来查看一下程序的内存使用，会得到下面的内容，其中RSS（resident set size）列表示真实占用的内存。&lt;/p&gt;&lt;pre&gt;pmap -x 12727&#xD;
12727:   ./mem_munch&#xD;
Address           Kbytes     RSS   Dirty Mode   Mapping&#xD;
0000000000400000       0       4       0 r-x--  mem_munch&#xD;
0000000000600000       0       4       4 r----  mem_munch&#xD;
0000000000601000       0       4       4 rw---  mem_munch&#xD;
000000000147d000       0       4       4 rw---    [ anon ]&#xD;
00007fe261c6f000       0       4       0 r--s-  random&#xD;
00007fe29d61c000       0     288       0 r-x--  libc-2.13.so&#xD;
00007fe29d7a6000       0       0       0 -----  libc-2.13.so&#xD;
00007fe29d9a5000       0      16      16 r----  libc-2.13.so&#xD;
00007fe29d9a9000       0       4       4 rw---  libc-2.13.so&#xD;
00007fe29d9aa000       0      16      16 rw---    [ anon ]&#xD;
00007fe29d9b0000       0     108       0 r-x--  ld-2.13.so&#xD;
00007fe29dba6000       0      12      12 rw---    [ anon ]&#xD;
00007fe29dbcc000       0      16      16 rw---    [ anon ]&#xD;
00007fe29dbd0000       0       4       4 r----  ld-2.13.so&#xD;
00007fe29dbd1000       0       8       8 rw---  ld-2.13.so&#xD;
00007ffff29b2000       0      12      12 rw---    [ stack ]&#xD;
00007ffff29de000       0       4       0 r-x--    [ anon ]&#xD;
ffffffffff600000       0       0       0 r-x--    [ anon ]&#xD;
----------------  ------  ------  ------&#xD;
total kB          980684     508     100&lt;/pre&gt;&#xD;
&lt;p sizcache="1" sizset="52"&gt;如果你的虚拟内存占用（上面的Kbytes列）都是0，不用担心，这是一个在Debian/Ubuntu系统上pmap -x命令的&lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=614513" target="_blank"&gt;bug&lt;/a&gt;。最后一行输出的总占用量是正确的。&lt;/p&gt;&#xD;
&lt;p&gt;现在你可以看一下RSS那一列，这就是实际内存占用。在random文件上，你的程序实际上可以访问在00007fe261c6f000之前的数十亿字节的内存地址，但是只要你访问的地址超过4KB，那么操作系统就会去磁盘上查找内容。也就是说实际上只有4KB的物理内存被使用了。只有访问这4KB的东西时，才是真正的内存操作。其它部分虽然你使用的也是内存操作函数来访问它，但是由于它没有被加载到内存中，所以在这些内容被访问的时候，操作系统会先去磁盘读random中读取内容到内存中。&lt;/p&gt;&#xD;
&lt;p&gt;如果我们把程序再修改一下，修改成下面这样，让程序把整个random文件都访问一遍。&lt;/p&gt;&lt;pre&gt;#include &amp;lt;stdio.h&amp;gt;&#xD;
#include &amp;lt;unistd.h&amp;gt;&#xD;
#include &amp;lt;sys/types.h&amp;gt;&#xD;
#include &amp;lt;stdlib.h&amp;gt;&#xD;
#include &amp;lt;sys/mman.h&amp;gt;&#xD;
&#xD;
int main() {&#xD;
  char *random_bytes;&#xD;
  FILE *f;&#xD;
  int offset = 0;&#xD;
&#xD;
  // open "random" for reading&#xD;
  f = fopen("/home/user/random", "r");&#xD;
  if (!f) {&#xD;
    perror("couldn't open file");&#xD;
    return -1;&#xD;
  }&#xD;
&#xD;
  random_bytes = mmap(0, 1000000000, PROT_READ, MAP_SHARED, fileno(f), 0);&#xD;
&#xD;
  if (random_bytes == MAP_FAILED) {&#xD;
    printf("error mapping the file\n");&#xD;
    return -1;&#xD;
  }&#xD;
&#xD;
  for (offset = 0; offset &amp;lt; 1000000000; offset += 4) {&#xD;
    int i = *(int*)(random_bytes+offset);&#xD;
&#xD;
    // to show we're making progress&#xD;
    if (offset % 1000000 == 0) {&#xD;
      printf(".");&#xD;
    }&#xD;
  }&#xD;
&#xD;
  // at the end, wait for signal so we can check mem&#xD;
  printf("\ndone, run `pmap -x %d`\n", getpid());&#xD;
  pause();&#xD;
}&lt;/pre&gt;&#xD;
&lt;p&gt;现在我们的pmap -x命令就会得到如下输出：&lt;/p&gt;&lt;pre&gt;$ pmap -x 5378&#xD;
5378:   ./mem_munch&#xD;
Address           Kbytes     RSS   Dirty Mode   Mapping&#xD;
0000000000400000       0       4       4 r-x--  mem_munch&#xD;
0000000000600000       0       4       4 r----  mem_munch&#xD;
0000000000601000       0       4       4 rw---  mem_munch&#xD;
0000000002271000       0       4       4 rw---    [ anon ]&#xD;
00007fc2aa333000       0  976564       0 r--s-  random&#xD;
00007fc2e5ce0000       0     292       0 r-x--  libc-2.13.so&#xD;
00007fc2e5e6a000       0       0       0 -----  libc-2.13.so&#xD;
00007fc2e6069000       0      16      16 r----  libc-2.13.so&#xD;
00007fc2e606d000       0       4       4 rw---  libc-2.13.so&#xD;
00007fc2e606e000       0      16      16 rw---    [ anon ]&#xD;
00007fc2e6074000       0     108       0 r-x--  ld-2.13.so&#xD;
00007fc2e626a000       0      12      12 rw---    [ anon ]&#xD;
00007fc2e6290000       0      16      16 rw---    [ anon ]&#xD;
00007fc2e6294000       0       4       4 r----  ld-2.13.so&#xD;
00007fc2e6295000       0       8       8 rw---  ld-2.13.so&#xD;
00007fff037e6000       0      12      12 rw---    [ stack ]&#xD;
00007fff039c9000       0       4       0 r-x--    [ anon ]&#xD;
ffffffffff600000       0       0       0 r-x--    [ anon ]&#xD;
----------------  ------  ------  ------&#xD;
total kB          980684  977072     104&lt;/pre&gt;&#xD;
&lt;p&gt;我们可以看到，random文件映射实际占用内存量已经和random文件大小一致了，也就是也random文件通过循环访问，其内容已经完全加载到内存中了。现在我们再访问random文件的任何部分，实际上都是内存操作。而不会穿透到磁盘。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/2180149.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180149.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180143.html</id><title type="text">WINDOWS进程或线程号为什么是4的倍数</title><summary type="text">今天看到一篇文章作者问为什么System进程号是4.记得之前在《windows内核原理与实现》里面看过，但是就是想不起来了。搜集了一些资料解释了原因。</summary><published>2011-09-18T01:53:00Z</published><updated>2011-09-18T01:53:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180143.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180143.html"/><content type="html">　　今天看到一篇文章作者问为什么System进程号是4.记得之前在《windows内核原理与实现》里面看过，但是就是想不起来了。搜集了一些资料解释了原因。&lt;span&gt; &#xD;
&lt;p&gt;原来进程Id和线程Id都是基于全局的句柄表PspCidTable生成，也就是句柄表的索引号。句柄表除了作为对象引用的容器以外，还有另一个用法：作为分配进程和线程的唯一ID 的有效手段。进程有一个唯一ID，称为UniqueProcessId；线程有一个CLIENT_ID 成员Cid，其中包含了所属进程的唯一ID 和线程自身的唯一ID。这些唯一ID 是怎么生成的呢？它们是通过调用ExCreateHandle 函数，在一个全局的句柄表PspCidTable 中创建的句柄索引值。此句柄表也称为CID 句柄表（Client ID handle table），它没有被加入到系统的句柄表链表中。CID 句柄表中的每个句柄表项都包含了进程或线程的对象地址。&lt;/p&gt;&#xD;
&lt;p&gt;因此，进程和线程的唯一ID 值都是4 的倍数，其中4 是第一个句柄索引值，它被分配给System 进程的唯一ID（因为System 进程是第一个通过PspCreateProcess 函数创建的进程）。0 是专门保留给空闲进程的，它并非通过ExCreateHandle 函数而获得。CID 句柄表严格按照FIFO 来重用句柄表项，所以，一个句柄表项被释放以后，要等到其他的空闲句柄表项都被重用一遍以后才会被再次使用。由于CID 句柄表项保存了进程或线程的对象地址，所以，在内核中，根据进程或线程的唯一ID 值，总是可以很方便地找到相应的对象地址，函数PsLookupProcessThreadByCid、PsLookupProcessByProcessId 和PsLookup-ThreadByThreadId 正是利用了CID 句柄表的这一能力，参见base\ntos\ps\pscid.c 文件中的代码。&lt;/p&gt;&#xD;
&lt;p&gt;PspCidTable的说明如下：&lt;/p&gt;&#xD;
&lt;p&gt;PspCidTable也是一个句柄表,其格式与普通的句柄表是完全一样的.但它与每个进程私有的句柄表有以下不同:&lt;br /&gt;1.PspCidTable中存放的对象是系统中所有的进线程对象,其索引就是PID和TID&lt;br /&gt;2.PspCidTable中存放的直接是对象体(EPROCESS和ETHREAD),而每个进程私有的句柄表则存放的是对象头(OBJECT_HEADER)&lt;br /&gt;3.PspCidTable是一个独立的句柄表,而每个进程私有的句柄表以一个双链连接起来。&lt;/p&gt;&#xD;
&lt;p&gt;至于为什么句柄表的号都是4的倍数呢？&lt;/p&gt;&#xD;
&lt;p&gt;一个进程的句柄表包含了所有已被该进程打开的那些对象的指针。对象句柄是用来检索句柄表的一个&amp;#8220;伪索引&amp;#8221;。对于句柄表机制，achillis &amp;lt;&amp;lt;Windows句柄表&amp;gt;&amp;gt;系列文章已经分析得很透彻了，只是对&amp;#8220;句柄以4为步进&amp;#8221;来源不明。经查，根源如下：&lt;/p&gt;&#xD;
&lt;p&gt;typedef struct _EXHANDLE&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;union&lt;br /&gt;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;struct&lt;br /&gt;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ULONG TagBits:2;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ULONG Index:30;&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;HANDLE GenericHandleOverlay; &lt;br /&gt;&amp;nbsp;&amp;nbsp;#define HANLE_VALUE_INC 4&lt;br /&gt;&amp;nbsp;&amp;nbsp;ULONG_PTR Value; &lt;br /&gt;&amp;nbsp;}&lt;/p&gt;&#xD;
&lt;p&gt;}EXHANDLE,*PEXHANDLE;&lt;br /&gt;此结构正是用来定义句柄类型。低2位TagBits为标志位Windows用于其它用途，故句柄值低2位对其作为句柄表索引本身无意义，所以等于4的倍数。有了以上分析，自然，在用句柄值为索引取句柄表项时，句柄值必须/4。因此程序中用到的句柄值并不能直接用来索引句柄表，也就有了&amp;#8220;伪索引&amp;#8221;说法。&lt;/p&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/2180143.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2011/09/18/2180143.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2011/05/30/2063829.html</id><title type="text">【知识总结】关于内存管理</title><summary type="text">频繁的内存申请，释放，拷贝应该得到优化!</summary><published>2011-05-30T15:12:00Z</published><updated>2011-05-30T15:12:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2011/05/30/2063829.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2011/05/30/2063829.html"/><content type="html">1.VM管理&lt;br /&gt;　　一般操作系统的用的都是基于VM的内存管理，这样可以扩展有效的物理内存，热点数据在物理内存中，非热点数据会进去页面文件后等后备存储中，需要时中断取出，对于系统或应用来说这一机制是透明的。&lt;br /&gt;&amp;nbsp;目前有些性能较好的缓存应用也在使用VM进行内存管理，例如redis，真正没有测试过，据说性能提升明显，从理论上说，缓存的热点数据和非热点数据应该分别对待，这种机制还是可取的。&lt;br /&gt;2.内存池&lt;br /&gt;　　这里所说的内存池就是指一些应用上程序上的内存池，例如c语言开发的程序一般会有专门的内存池来管理内存，例如nignx的内存池。内存池存在的意义主要在于减少频繁的分配和释放内存(一般是操作系统的VM内存管理中保留和归还操作)，这一部分相对于IO来说消耗比较少，但是对于内存的频繁使用消耗就会比较明显。还有就是可以减少内存泄漏和内存碎片的产生。&lt;br /&gt;3.GC管理&lt;br /&gt;　　一些很高级的语言提供了GC管理的机制，例如C#或Java等，其实GC本身就是一个大的内存池，托管堆就是GC管理的对象，只不过这个内存池来说比较高级而已，算法比较适合于业务语言的需求。其实C#使用特殊的函数完全可以从非托管堆上分配内存，也可以实现一个高性能的内存池，这样GC的压力就会降下来，当然这都是对于大量而且频繁的内存使用而言，否则完全没有必要。&lt;br /&gt;4.对象池&lt;br /&gt;　　对于一些使用C#或Java开发的应用来说，如果面临着同一种类型的大量对象的new操作，而且马上使用完了，GC可能就可以回收的情形来说，可以尝试使用一下对象池(连接池，线程池也可以算)。对象池一般是给一个初始的容量参数，一次性或多次创建很多对象，每次需要创建时取一个即可使用，使用完了主动归还，如果不归还可能也会内存泄漏，因为对象池还在引用它（如果算法写好了应该可以收回）,对象池对于以上频繁的创建生命周期很短的对象来说很有效，可以明显降低GC的压力，留出更多的CPU时间给业务使用。 &#xD;
&lt;p&gt;&lt;span&gt;5.总结&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;　　频繁的内存申请，释放，拷贝应该得到优化!&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/2063829.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2011/05/30/2063829.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1916137.html</id><title type="text">【知识分享】异步调用与多线程的区别</title><summary type="text">随着拥有多个硬线程CPU（超线程、双核）的普及，多线程和异步操作等并发程序设计方法也受到了更多的关注和讨论。本文主要是想探讨一下如何使用并发来最大化程序的性能。</summary><published>2010-12-24T08:45:00Z</published><updated>2010-12-24T08:45:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1916137.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1916137.html"/><content type="html">&lt;p&gt;随着拥有多个硬线程CPU（超线程、双核）的普及，多线程和异步操作等并发程序设计方法也受到了更多的关注和讨论。本文主要是想探讨一下如何使用并发来最大化程序的性能。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;多线程和异步操作的异同&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;多线程和异步操作两者都可以达到避免调用线程阻塞的目的，从而提高软件的可响应性。甚至有些时候我们就认为多线程和异步操作是等同的概念。但是，多线程和异步操作还是有一些区别的。而这些区别造成了使用多线程和异步操作的时机的区别。多线程是实现异步的一个重要手段，但不是唯一手段，对以一个单线程程序也可以是异步执行的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;异步操作的本质&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所有的程序最终都会由计算机硬件来执行，所以为了更好的理解异步操作的本质，我们有必要了解一下它的硬件基础。 熟悉电脑硬件的朋友肯定对DMA这个词不陌生，硬盘、光驱的技术规格中都有明确DMA的模式指标，其实网卡、声卡、显卡也是有DMA功能的。DMA就是直 接内存访问的意思，也就是说，拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。只要CPU在发起数据传输时发送一个指令，硬件就开 始自己和内存交换数据，在传输完成之后硬件会触发一个中断来通知操作完成。这些无须消耗CPU时间的I/O操作正是异步操作的硬件基础。所以即使在DOS 这样的单进程（而且无线程概念）系统中也同样可以发起异步的DMA操作。异步编程的目的就是为了能够是实现并行，但不仅是提高多处理器间的并行度，同时也是提高处理器与I/O处理器的并行度。非阻塞模式一般特指异步的I/O 操作，可以算是异步编程的一种类型。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;线程的本质&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;线程不是一个计算机硬件的功能，而是操作系统提供的一种逻辑功能，线程本质上是进程中一段并发运行的代码，所以线程需要操作系统投入CPU资源来运行和调度。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;异步操作的优缺点&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;因为异步操作无须额外的线程负担，并且使用回调的方式进行处理，在设计良好的情况下，处理函数可以不必使用共享变量（即使无法完全不用，最起码可以减少 共享变量的数量），减少了死锁的可能。当然异步操作也并非完美无暇。编写异步操作的复杂程度较高，程序主要使用回调方式进行处理，与普通人的思维方式有些初入，而且难以调试。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;多线程的优缺点&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;多线程的优点很明显，线程中的处理程序依然是顺序执行，符合普通人的思维习惯，所以编程简单。但是多线程的缺点也同样明显，线程的使用（滥用）会给系统带来上下文切换的额外负担。并且线程间的共享变量可能造成死锁的出现。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;适用范围&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在了解了线程与异步操作各自的优缺点之后，我们可以来探讨一下线程和异步的合理用途。我认为：当需要执行I/O操作时，使用异步操作比使用线程+同步 I/O操作更合适。I/O操作不仅包括了直接的文件、网络的读写，还包括数据库操作、Web Service、HttpRequest以及.net Remoting等跨进程的调用。而线程的适用范围则是那种需要长时间CPU运算的场合，例如耗时较长的图形处理和算法执行。但是往 往由于使用线程编程的简单和符合习惯，所以很多朋友往往会使用线程来执行耗时较长的I/O操作。这样在只有少数几个并发操作的时候还无伤大雅，如果需要处 理大量的并发操作时就不合适了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;对于CPU来说以下意味着什么&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;线程：意味了CPU的一组寄存器&lt;/p&gt;&#xD;
&lt;p&gt;进程：意味着CPU的页目录寄存器&lt;/p&gt;&#xD;
&lt;p&gt;IO：意味着一些端口或内存地址空间中一些地址&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;  &lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1916137.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1916137.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1915909.html</id><title type="text">【知识分享】了解WINDOWS内核的关键组件和功能</title><summary type="text">通过WRK可以了解到，WINDOWS内核绝大部分源代码是由C语言实现，只有部分与处理器相关的调度代码是通过汇编语言实现。最近半年我对WINDOWS平台本身有很高的兴趣，其实我作为应用程序开发人员对于WINDOWS内核没有必要知道的太多，但是了解下不仅对我应用程序排查问题有帮助，而且WINDOWS内核中有很多良好的设计也是我们应用开发人员值得学习的，例如说内存堆管理，IO体现等，甚至可以引用到自己的项目中。很多程序员和架构师每天围绕WINDOWS展开工作，因为我们的程序就是基于WINDOWS的，WINDOWS占领了PC的市场，关键是不得不用。我们开发的程序可以认为是WINDOWS能力的扩展，在WINDWOS平台下的主要扩展方式有以下几种：窗体应用程序，控制台应用程序，服务程序，驱动程序（可以认为是内核模块的扩展），本地程序。</summary><published>2010-12-24T05:48:00Z</published><updated>2010-12-24T05:48:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1915909.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1915909.html"/><content type="html">&lt;p&gt;通过WRK可以了解到，WINDOWS内核绝大部分源代码是由C语言实现，只有部分与处理器相关的调度代码是通过汇编语言实现。最近半年我对WINDOWS平台本身有很高的兴趣，其实我作为应用程序开发人员对于WINDOWS内核没有必要知道的太多，但是了解下不仅对我应用程序排查问题有帮助，而且WINDOWS内核中有很多良好的设计也是我们应用开发人员值得学习的，例如说内存堆管理，IO体现等，甚至可以引用到自己的项目中。很多程序员和架构师每天围绕WINDOWS展开工作，因为我们的程序就是基于WINDOWS的，WINDOWS占领了PC的市场，关键是不得不用。我们开发的程序可以认为是WINDOWS能力的扩展，在WINDWOS平台下的主要扩展方式有以下几种：窗体应用程序，控制台应用程序，服务程序，驱动程序（可以认为是内核模块的扩展），本地程序。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.扩展类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;窗体应用程序&lt;/strong&gt;：这个大家最熟悉不过了，直接用MFC写一个窗体程序，用Winform写一个窗体程序。窗体程序一般都需要在某个用户的Session的桌面中运行，基于WINDOWS子系统，采用GDI做显示输出技术，基于WINDOWS的消息机制，有消息循环和窗体函数，所以窗体程序会有大量的GDI对象生成，窗体应用程序也是WINDOWS作为客户端系统最为普遍的应用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;控制台应用程序&lt;/strong&gt;：控制台的程序是最早的DOS下16位应用在WINDOWS下的兼容方式（不过现在已经是32位为主了），有标准输入，标准输出和标准错误，一般是作为计算机管理人员使用。控制台程序与WINDWOS窗体应用的运行机制完全不同，窗体程序是基于GDI，内核级由win32k.sys处理，而控制台应用程序一般由csrss.exe（下文会有介绍）管理。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;服务程序&lt;/strong&gt;：这是WINDOWS作为服务器端应用时普遍采用的方式，具有守护特性（无需用户登录无需退出），类似与LINUX下的DAEMON进程，服务程序的运行不需要用户登录，一般由LOCAL SERVICE，NETWORK SERVICE，SYSTEM用户运行，所以没有用户界面，所以成为服务器端的主要应用方式是因为这种服务程序很多都是使用线程池来做IO处理，例如处理网络连接和数据库操作等。此前之前有人试图在WINDOWS服务中启动用户界面程序，虽然可能通过一些技巧会实现，但是这种不是服务程序设计的初衷，只能说明应用架构设计的不合理。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;驱动程序&lt;/strong&gt;：这里的驱动程序特指运行在WINDOWS内核模式下的扩展模块或设备驱动程序，WINDOWS内核通过IO管理器等执行体模块对驱动程序进行管理，可以是协议驱动程序，设备驱动程序，文件系统驱动程序等，一般基于一定的驱动程序开发模型由第三方提供。此外WINDOWS对于驱动程序的一个映像只允许加载一次，也就是说两个驱动程序不能使用同一个映像文件。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;本地程序&lt;/strong&gt;：这个可能大家最为陌生，本地程序不是我们常说的WIN32本地程序，WIN32本地程序是指基于WINDOWS子系统的本地代码程序。而这里的本地程序是WINDOWS的原生程序，一般直接基于ntdll.dll,而不是基于user32.dll，kernel32.dll等子系统dll。举个例子就是WINDOWS的第一个用户态进程smss.exe，完成会话管理任务和启动一些其他子系统进程。还有就是我们常用的瑞星杀毒软件在启动的时候会执行内核扫描，实际上这个程序就是本地程序。&lt;/p&gt;&#xD;
&lt;p&gt;所有以上程序都可以使用VS开发，只是改变一些配置选项，需要安装例如WINDOWS SDK和WINDOWS DDK等开发包。&lt;/p&gt;&#xD;
&lt;p&gt;其他一些扩展，例如WINDOWS的SHELL程序explorer.exe的扩展，IE浏览器的插件，还有就是登录认知的GINA扩展等。目前SHELL编程已经成为独立的开发方向。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.内核模块&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;看一副经典的图片吧，这是一幅WINDOWS内核组件的原图，这里的内核是指大内核，而不是图中的kernel的微内核，微内核是特指线程调度模块。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/thriving-country/kernel.png" width="559" height="603" /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在WINDOWS中可执行的代码在CPU上运行时会有用户模式和内核模式两种，CPU不是工作在内核模式就是工作在用户模式，一般用户模式在CPU的低权限级别运行，当线程运行在用户模式时只能访问进程空间的资源，对于32位系统只能使用2GB以下地址空间(最大3GB)，如果需要访问其他资源需要陷入内核模式。当线程工作在内核态时能够访问到4GB全地址空间，包括系统空间的映射。图中NTDLL正是将用户态和内核态隔开的模块，NTDLL通过特殊的CPU指令可以进入内核态，反之亦然。&lt;br /&gt;用户态中包括应用程序，子系统，服务和一些系统管理进程，最后都是通过NTDLL进入内核态的。&lt;br /&gt;内核态中包括SDT（服务分发表，系统线程），执行体（包括内存管理，进程线程管理，IO管理等），微内核（调度）。此外还包括第三方的驱动程序（其实很多也是MICROSOFT提供的），和WINDOWS的子系统内核模块win32k.sys。&lt;br /&gt;内核态还有一个很重要的hal.dll，实现WINDOWS内核的跨平台（硬件平台）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.重要文件&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Ntoskrnl.exe: 包含执行体和内核部分，是大内核的主要部分，完全运行在内核态，可以说是WINDOWS系统的核心部分。WRK的源代码就是这一部分。&lt;/p&gt;&#xD;
&lt;p&gt;Ntkrnlpa.exe (32位): Ntoskrnl的PAE版本。&lt;/p&gt;&#xD;
&lt;p&gt;Hal.dll：硬件抽象层，WINDOWS的跨平台特性很多就要从这个文件说起，一共大概4个版本，在WINDOWS系统安装时会根据硬件平台选择一个进行拷贝之后重命名。&lt;/p&gt;&#xD;
&lt;p&gt;Win32k.sys: WINDOWS子系统的内核部分，包括了消息，图形的内核部分等。窗口显示；鼠标、键盘输入接收；传递用户消息，GDI。&lt;/p&gt;&#xD;
&lt;p&gt;Ntdll.dll：用户态子系统DLL。&lt;/p&gt;&#xD;
&lt;p&gt;Kernel32.dll，Advapi32.dll，User32.dll，Gdi32.dll：一些用户态的WINDOWS子系统DLL，WINDOWS共支持三种子系统WINDOWS，POSIX，OS/2。将documented Windows API映射到undocumented的kernel-mode system service call。&lt;/p&gt;&#xD;
&lt;p&gt;Csrss.exe：Console管理，创建/销毁进程和线程，支持16位进程。&lt;/p&gt;&#xD;
&lt;p&gt;Ntdll.dll：User-mode应用调用到Windows executive system service的接口，Subsystem, native images的内部支持。&lt;/p&gt;&#xD;
&lt;p&gt;Idle process：一个CPU一个线程，用来计算CPU空闲时间，进程编号为0，一般由WINDOWS的初始化程序退化而成。无映像文件。&lt;/p&gt;&#xD;
&lt;p&gt;System process系统，进程编号为4，一些系统线程会被附加在此进程中，无映像文件。&lt;/p&gt;&#xD;
&lt;p&gt;Smss.exe：第一个user-mode进程。&lt;/p&gt;&#xD;
&lt;p&gt;Winlogon.exe：登录界面。可替换。GINA。&lt;/p&gt;&#xD;
&lt;p&gt;Services.exe and Svchost.exe：服务管理和宿主进程。&lt;/p&gt;&#xD;
&lt;p&gt;Lsass.exe：验证用户登录信息。&lt;/p&gt;&#xD;
&lt;p&gt;Userinit.exe:&amp;nbsp; 初始化用户信息，执行shell程序（explorer.exe）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.重要部分&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;内存管理&lt;br /&gt;同步和线程调度&lt;br /&gt;IO系统&lt;br /&gt;服务分发&lt;br /&gt;进程通信&lt;br /&gt;网络系统&lt;br /&gt;文件系统&lt;br /&gt;WINDOWS子系统&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.推荐资源&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;《WINDOWS核心编程》&lt;br /&gt;《深入解析WINDOWS内核》&lt;br /&gt;《WINDOWS内核原理与应用》&lt;br /&gt;Sysinternals工具&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;谢谢收看，有问题一起讨论！&lt;/strong&gt;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1915909.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/24/1915909.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/12/21/1912444.html</id><title type="text">【经验总结】C#常用线程同步方法应用场景和实现原理</title><summary type="text">简单描述volatile，Interlocked，lock，Mutex，Semaphore，Spin lock，AutoResetEvent，ManualResetEvent，ReaderWriterLockSlim，MethodImplAttribute，WaitHandle常用同步机制的原理和使用场景。</summary><published>2010-12-21T03:31:00Z</published><updated>2010-12-21T03:31:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/21/1912444.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/21/1912444.html"/><content type="html">&lt;p&gt;简单描述volatile，Interlocked，lock，Mutex，Semaphore，Spin lock，AutoResetEvent，ManualResetEvent，ReaderWriterLockSlim，MethodImplAttribute，WaitHandle常用同步机制的原理和使用场景。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;volatile&lt;br /&gt;只是C#的一个关键字，告诉编译器不能将声明的这个变量进行CPU内部缓存，只能在主内存中操作，类型有限制，volatile并不能实现真正的同步，因为它的操作级别只停留在变量级别，而不是原子级别。如果是在单处理器系统中，是没有任何问题的，变量在主存中没有机会被其他人修改，因为只有一个处理器，这就叫作processor Self-Consistency。但在多处理器系统中，可能就会有问题。 每个处理器都有自己的data cache，而且被更新的数据也不一定会立即写回到主存。所以可能会造成不同步，但这种情况很难发生，因为cache的读写速度相当快，flush的频率也相当高，只有在压力测试的时候才有可能发生，而且几率非常非常小。本质上说并非绝对的同步方法。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Interlocked&lt;br /&gt;对于例如int变量等的原子操作，效率高，可靠性高，一般通过CPU的专用指令实现的锁住内存总线实现的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;lock&lt;br /&gt;lock与Monitor本身是一致的，lock是做到了C#的关键字一级，是.net对象自身支持的的一种同步机制，对象中有相关的结构支持这种轻量级的线程同步，实现机制类似于CRITICAL_SECTION，但是CRITICAL_SECTION具有跨进程特性，而lock只能实现同一进程中的线程同步，在C#开发中很常用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Mutex&lt;br /&gt;是WIN32下的突变体内核对象的封装，类似于一间屋子只能进入一个人。是它的一个.net封装，效率比较低，由于突变体是一种windows内核对象，需要开销很大，但是支持跨进程，通过给Mutex命名的方式支持进程间同步，甚至可以跨服务器访问，是一种服务器之间同步的选择。Mutex的拥有者才能释放这个Mutex，其他进程不能释放，可能是考虑到安全问题。Mutex是一种基于线程调度的同步方式，控制的是线程的调度，实现了sleep，如果有信号可以通知内核线程调度程序调度等待线程。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Semaphore(Binary semaphore)&lt;br /&gt;基于WIN32的Semaphore，也是一种基于线程调度，基本很类似于Mutex，与Mutex不同之处在于Semaphore允许多人进入同一间屋子，使用count计数来实现，当允许数量为1时叫做Binary semaphore，这时候就是基本和Mutex很类似的，但是没有Mutex拥有者一说，可由任何进程进行资源释放。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Spin lock&lt;br /&gt;这是一个内核态概念。spin lock与semaphore的主要区别是spin lock是busy waiting，而semaphore是sleep。对于可以sleep的进程来说，busy waiting当然没有意义，CPU只是在那里空转而已，而且IRQL比较高，适合于等待时间比较短的场景。对于单CPU的系统，busy waiting当然更没意义（没有CPU可以释放锁），所有Spin lock只对多CPU才有意义，因此，只有多CPU的内核态非进程空间，才会用到spin lock。其实也就是类似mutex的作用，串行化对 critical section的访问。但是mutex不能保护中断的打断，也不能在中断处理程序中被调用。而spin lock也一般没有必要用于可以sleep的进程空间。幸好它是内核级的，如果是用户级的会很危险。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;AutoResetEvent，ManualResetEvent&amp;nbsp; (Event)&lt;br /&gt;这两种的实现都是基于WIN32的Event原理，同步事件有两种：AutoResetEvent 和 ManualResetEvent。它们之间唯一的不同在于，无论何时，只要 AutoResetEvent 激活线程，它的状态将自动从终止变为非终止。相反，ManualResetEvent 允许它的终止状态激活任意多个线程，只有当它的 Reset 方法被调用时才还原到非终止状态。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;ReaderWriterLockSlim&lt;br /&gt;这个也是lock的封装，对资源的访问方式有共享和独占方式，例如我们控制对某个资源读贡献或者写独占，那么这个类可以派上用场。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;SynchronizationAttribute ，MethodImplAttribute&lt;br /&gt;这两个属于类特性和方法的特性，标识某个类或方法是同步方法，本质上基于lock的实现。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;WaitHandle&lt;br /&gt;可以通过调用一种等待方法，如 WaitOne、WaitAny 或 WaitAll，让线程等待事件。System.Threading.WaitHandle.WaitOne 使线程一直等待，直到单个事件变为终止状态；System.Threading.WaitHandle.WaitAny 阻止线程，直到一个或多个指示的事件变为终止状态；System.Threading.WaitHandle.WaitAll 阻止线程，直到所有指示的事件都变为终止状态。当调用事件的 Set 方法时，事件将变为终止状态。WaitOne基于WaitSingleObject，WaitAny 或 WaitAll基于WaitmultipleObject，具体由后面参数来决定。WaitmultipleObject实现要比WaitSingleObject复杂的多，性能也不好，尽量少用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;   &lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1912444.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/12/21/1912444.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/08/26/1809017.html</id><title type="text">【代码分享】写一个RPC批量调用支持（支持串行和并行模式）</title><summary type="text">我在做项目过程中遇到这方面的问题，于是自己封装了一个组件来解决RPC的批量调用问题（需要获取每个RPC的返回结果），批量中的量最好也别太大，否则不是等待时间很长就是耗费很多线程。</summary><published>2010-08-26T05:45:00Z</published><updated>2010-08-26T05:45:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/26/1809017.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/26/1809017.html"/><content type="html">&lt;p&gt;我在做项目过程中遇到这方面的问题，于是自己封装了一个组件来解决RPC的批量调用问题（需要获取每个RPC的返回结果），批量中的量最好也别太大，否则不是等待时间很长就是耗费很多线程。&lt;/p&gt;&#xD;
&lt;p&gt;问题描述：对外需要提供一个异步RPC接口，但是对方要求是可以批量查询某些数据，内部也有类似的异步RPC接口，但是是单条查询。我这里需要做一个转换，需要将批量的拆分路由给单条的。而且类似这种需求的接口还挺多。所以为了代码简洁，控制上通用和规范些。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;难点：&lt;br /&gt;1.代码控制上，由于涉及很多异步回调+批量增加代码难度。&lt;br /&gt;2.需要考虑各种异常和不hang住线程。&lt;br /&gt;3.更好考虑到性能问题，批量的也许会对内部单条的接口造成压力。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本类库支持两种方案，也就是两种运行模式：&lt;br /&gt;1.串行处理，也就是对于收到的批量的调用之后，一条一条处理，在第一条回调返回结果时再去执行第二条处理，依次类推指导所有调用处理完成为止。中间如果出现异常可以选择继续执行或中断返回整个处理结果。&lt;br /&gt;2.串行处理，利用.net4.0提供的并行能力，使用任务处理批量的异步调用，并行库完成了一些同步机制，可以在全部单条调用结果返回时执行返回批量调用的结果。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;串行方式可能执行时间比较长（与批量的条数有关），而串行方式可能需要很多线程并行参与，需要线程切换和同步比较多。对于一些性能要求比较高的推荐使用串行方式，对于一些要求返回结果比较快的推荐并行方式。一般RPC都属于IO密集型操作，而且每条之间比较独立，所以很适合任务处理。&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;运行结果：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;流水线开始...&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:0 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:1 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:2 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:3 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:4 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:5 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:6 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:7 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:8 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:9 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:10 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:11 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:12 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:13 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:14 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:15 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:16 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:17 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:18 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:19 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:20 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:21 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:22 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:23 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:24 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:25 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:26 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:27 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:28 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Proc:29 OK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：100&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：101&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：102&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：103&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：104&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：105&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：106&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：107&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：108&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：109&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：110&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：111&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：112&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：113&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：114&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：115&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：116&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：117&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：118&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：119&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：120&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：121&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：122&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：123&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：124&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：125&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：126&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：127&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：128&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;返回最终结果：129&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;00:00:00.51&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="源代码下载" href="http://files.cnblogs.com/Thriving-Country/RpcBatchEx20100826/RpcBatchEx.rar"&gt;源代码提供下载&lt;/a&gt;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1809017.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/26/1809017.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/08/21/1805508.html</id><title type="text">【经典问题】现代操作系统经典问题回顾（哲学家就餐问题C#实现）</title><summary type="text">在1971年，著名的计算机科学家艾兹格·迪科斯彻提出了一个同步问题，即假设有五台计算机都试图访问五份共享的磁带驱动器。稍后，这个问题被托尼·霍尔重新表述为哲学家就餐问题。这个问题可以用来解释死锁和资源耗尽。</summary><published>2010-08-21T13:10:00Z</published><updated>2010-08-21T13:10:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/21/1805508.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/21/1805508.html"/><content type="html">&lt;p&gt;在1971年，著名的计算机科学家艾兹格&amp;#183;迪科斯彻提出了一个同步问题，即假设有五台计算机都试图访问五份共享的磁带驱动器。稍后，这个问题被托尼&amp;#183;霍尔重新表述为哲学家就餐问题。这个问题可以用来解释死锁和资源耗尽。&lt;/p&gt;&#xD;
&lt;p&gt;哲学家就餐问题描述：五个哲学家围坐在一张圆桌周围，每个哲学家面前都有一盘通心粉。由于通心粉很光滑，所以需要两把叉子才能夹住，相邻两个盘子之间放有一把叉子。哲学家的生活中有两种交替活动时段：即吃饭和思考（一种抽象而已）。当一个哲学家觉得饿了时，他就试图分两次去取其左边和右边的叉子，每次拿到一把，但不分次序。如果成功地得到了两把叉子，就开始吃饭，吃完后放下叉子继续思考。问题是为哲学家写一段描述其行为的程序，且决不会死锁。&lt;/p&gt;&#xD;
&lt;p&gt;源码：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('bad5f26c-111f-4c01-9b25-489cbdadba0f')"&gt;&lt;img style="display: none" id="code_img_opened_bad5f26c-111f-4c01-9b25-489cbdadba0f"  onclick="cnblogs_code_hide('bad5f26c-111f-4c01-9b25-489cbdadba0f',event)" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif"&gt; &#xD;
&lt;div id="cnblogs_code_open_bad5f26c-111f-4c01-9b25-489cbdadba0f" &gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;************************************************************&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;在1971年，著名的计算机科学家艾兹格&amp;#183;迪科斯彻提出了一个同步问题，&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;即假设有五台计算机都试图访问五份共享的磁带驱动器。稍后，这个问&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;题被托尼&amp;#183;霍尔重新表述为哲学家就餐问题。这个问题可以用来解释死&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;锁和资源耗尽。&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;哲学家就餐问题描述：五个哲学家围坐在一张圆桌周围，每个哲学家面&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;前都有一盘通心粉。由于通心粉很光滑，所以需要两把叉子才能夹住，&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;相邻两个盘子之间放有一把叉子。哲学家的生活中有两种交替活动时段：&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;即吃饭和思考（一种抽象而已）。当一个哲学家觉得饿了时，他就试图&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;分两次去取其左边和右边的叉子，每次拿到一把，但不分次序。如果成功&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;地得到了两把叉子，就开始吃饭，吃完后放下叉子继续思考。问题是为&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;哲学家写一段描述其行为的程序，且决不会死锁。&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;国兴旺&amp;nbsp;2010/08/21&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;************************************************************&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Collections.Generic;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Linq;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Text;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;DiningPhilosophers&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;哲学家就餐问题是现代操作系统中很经典的问题。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;一个哲学家的封装。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;国兴旺&amp;nbsp;2010/08/21&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher&amp;nbsp;:&amp;nbsp;WorkerThread&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;READY&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;EATING&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;THINKING&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FINISHED&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;3&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;data)&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;base&lt;/span&gt;&lt;span style="color: #000000"&gt;(data)&amp;nbsp;{&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedHandler(Object&amp;nbsp;sender,&amp;nbsp;StateSwitchedEventArgs&amp;nbsp;args);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedHandler&amp;nbsp;StateSwitch;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;override&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Run()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PhilosopherData&amp;nbsp;pd&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(PhilosopherData)Data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Random&amp;nbsp;rnd&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Random(pd.PhilosopherId);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StateSwitch(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs(READY,&amp;nbsp;pd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WaitHandle[]&amp;nbsp;forks&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;WaitHandle[]&amp;nbsp;{&amp;nbsp;pd.LeftFork,&amp;nbsp;pd.RightFork&amp;nbsp;};&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;while&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(pd.TotalFood&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;如果两边的哲学家有拿着叉子的，则等待。&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WaitHandle.WaitAll(forks);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;否则，开始吃通心粉。&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StateSwitch(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs(EATING,&amp;nbsp;pd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;饭吃掉一部分移除。&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.TotalFood&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;pd.AmountToEat;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(rnd.Next(&lt;/span&gt;&lt;span style="color: #800080"&gt;100&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1000&lt;/span&gt;&lt;span style="color: #000000"&gt;));&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;模拟正在吃通心粉&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StateSwitch(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs(THINKING,&amp;nbsp;pd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;放下左边和右边的叉子开始思考。&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.RightFork.ReleaseMutex();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.LeftFork.ReleaseMutex();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thread.Sleep(rnd.Next(&lt;/span&gt;&lt;span style="color: #800080"&gt;100&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1000&lt;/span&gt;&lt;span style="color: #000000"&gt;));&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;模拟正在思考&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;至此，通信粉都吃完了。&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;StateSwitch(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs(FINISHED,&amp;nbsp;pd));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;哲学家相当于一个线程，这是工作线程抽象类，作为对线程操作的封装。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;国兴旺&amp;nbsp;2010/08/21&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;WorkerThread&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;_threadData;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Thread&amp;nbsp;_rawThread;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Data&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;_threadData;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;_threadData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;WorkerThread(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;object&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;data)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_threadData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;data;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;WorkerThread()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_threadData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Start()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_rawThread&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Thread(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;ThreadStart(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.Run));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_rawThread.Start();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;abstract&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Run();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;封装哲学家数据的结构。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;国兴旺&amp;nbsp;2010/08/21&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;struct&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;PhilosopherData&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;PhilosopherId;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;代表哲学家&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Mutex&amp;nbsp;RightFork;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;代表右边的叉子&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Mutex&amp;nbsp;LeftFork;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;代表左边的叉子&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;AmountToEat;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;吃掉的通心粉&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;TotalFood;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;盘中的总的通心粉&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;事件：用来通知外部现在哲学家的状态。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;国兴旺&amp;nbsp;2010/08/21&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs&amp;nbsp;:&amp;nbsp;EventArgs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;type;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;PhilosopherData&amp;nbsp;philosopherData;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;StateSwitchedEventArgs(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t,&amp;nbsp;PhilosopherData&amp;nbsp;pd)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;type&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;t;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;philosopherData&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;pd;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Collections.Generic;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Linq;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Text;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;DiningPhilosophers&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Program&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Main(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;args)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;准备数据&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Mutex[]&amp;nbsp;forks&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Mutex[N];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;forks[i]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Mutex(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;开始时叉子放在桌子上，没有哲学家拿到。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Philosopher[]&amp;nbsp;p&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher[N];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PhilosopherData&amp;nbsp;pd;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.PhilosopherId&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.RightFork&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;forks[(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N];&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;右边的叉子编号&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.LeftFork&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;forks[(i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;-&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1&lt;/span&gt;&lt;span style="color: #000000"&gt;)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;%&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N];&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;左边的叉子编号&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.AmountToEat&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N_EAT;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;暂时大锅饭，大家都一样。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pd.TotalFood&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N_TOTAL;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;暂时大锅饭，大家都一样。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p[i]&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher(pd);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p[i].StateSwitch&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+=&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher.StateSwitchedHandler(&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(sender,&amp;nbsp;data)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;Philosopher:{0}&amp;nbsp;IS&amp;nbsp;{1}.&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;data.philosopherData.PhilosopherId,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TranslateState(data.type));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p[i].Start();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.ReadKey();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;TranslateState(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;state)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;switch&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(state)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;case&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher.READY:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;READY&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;case&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher.EATING:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;EATING&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;case&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher.THINKING:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;THINKING&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;case&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Philosopher.FINISHED:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;FINISHED&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;default&lt;/span&gt;&lt;span style="color: #000000"&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;throw&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Exception(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;*NOT*&amp;nbsp;FOUND.&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;5&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;哲学家或叉子数目。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N_EAT&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;2&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;每次吃掉的通心粉数量。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;const&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;N_TOTAL&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;20&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;盘中通心粉总数。&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;运行结果：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS READY.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS READY.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS READY.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS READY.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS READY.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:1 IS FINISHED.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:4 IS FINISHED.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:3 IS FINISHED.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS EATING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:0 IS FINISHED.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS THINKING.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Tahoma; color: #0000ff; font-size: 10pt"&gt;Philosopher:2 IS FINISHED.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a title="哲学家就餐问题C#源码下载" href="http://files.cnblogs.com/Thriving-Country/DiningPhilosophers20100821/DiningPhilosophers.rar"&gt;源码下载&lt;/a&gt;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1805508.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/08/21/1805508.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2010/07/31/1789253.html</id><title type="text">【基本原理】使用托管代码实现一个寄宿ASP.NET的HTTP服务器（上）</title><summary type="text">在这两篇文章中我将带着大家实现一个简单的ASP.NET的寄宿环境，本文是第一部分，主要讲述一些原理性的内容，其中大多使用自己的通俗的语言描述一些概念和基础性的内容，为了给读者带来更多的认识，本文也解释了一些最原始的概念，有些内容是自己的总结，如有不对或理解不一致的地方请读者指出。唉，本人实在不善于写文章，写了只是为了总结一些。</summary><published>2010-07-31T04:22:00Z</published><updated>2010-07-31T04:22:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2010/07/31/1789253.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2010/07/31/1789253.html"/><content type="html">&lt;p&gt;在这两篇文章中我将带着大家实现一个简单的ASP.NET的寄宿环境，本文是第一部分，主要讲述一些原理性的内容，其中大多使用自己的通俗的语言描述一些概念和基础性的内容，为了给读者带来更多的认识，本文也解释了一些最原始的概念，有些内容是自己的总结，如有不对或理解不一致的地方请读者指出。唉，本人实在不善于写文章，写了只是为了总结一些。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.ASP.NET的Pipeline模型&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;ASP.NET随着.NET Framework一起分发，从1.0开始就一直以IIS作为寄宿环境。ASP.NET更是一个HTTP的处理引擎，内部实现了一套Pipeline模型，实现流水线处理请求的设计，从构造上线文环境（HttpContext）开始，经过一系列的过滤器（HttpModule，至于如何安装网上已经有很多介绍，HttpModule类似win32下的钩子Hook，可以做一些过滤处理，很实用的），请求会被送达处理器（HttpHandler，这个处理器可以完成对这个请求的最终处理），最后再经过一些过滤器而通过寄宿环境返回给客户端。需要说明的是这个Pipeline是一些讲述ASP.NET Runtime的文章中经常提到的概念，学习win32的同学们千万不要把这个Pipeline理解成Windows下的匿名或命名管道，它们完全是两个不同的概念，最初学习时很容易混淆，虽然在IIS内处理请求时与ASP.NET的WORKER进程之间通信等很多地方采用了命名管道，但是他们也不是一回事。至于讲述ASP.NET中Pipeline详细的文章网上到处都是，这里只是提及而已。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.IIS的寄宿ASP.NET的基本工作原理&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这里提及一下IIS的进程模型，IIS的进程模型从IIS5到IIS6是一个很大的飞跃，主要是IIS6把http协议栈实现在了内核模式中，那就是http.sys协议型驱动程序。这对于Windows作为Http服务器的性能是一个很大的提升，http.sys完成了连接的管理和请求路由（根据配置路由给相应的工作进程处理，这个配置可根据IIS的配置动态调整），http.sys与tcp.sys类似都是内核级的协议驱动程序，http.sys构建在tcpip.sys之上，就像http使用tcp协议承载一样，但是tcpip.sys实现的不仅是tcp/ip协议栈，它实现了很多协议的处理。在IIS5中使用socket处理http协议，但是socket是在用户态下运行的，所以处理http请求时会有大量的CPU从用户态和核心态之间的切换过程，这种切换的代价还是很大的，这对于大并发的http请求是不适合的。socket（这里的socket确切的说应该是 win sock）依赖于tcpip.sys完成标准接口功能，而tcpip.sys运行在内核态。从Windows xp sp2和Windows server 2003以后的操作系统中，微软提供了http.sys，http.sys在处理请求时，只有对于有必要投递给WORKER进程的请求，http.sys才会把请求数据根据动态的路由表路由给相应的进程处理。而且http.sys还完成了以下工作：如果当前要路由的进程没有启动，那么它会缓存住这个请求（放入请求队列中），直到有工作进程处理这个请求它才会投递。毫不夸张的说IIS在http.sys出现以后才成为真正的Http服务器。&lt;/p&gt;&#xD;
&lt;p&gt;这里插一句：之前有人曾经问过java与.net相互调用有几种方式，之后有人会说使用webservice，socket等。从上文的分析来看这种说法可能不太合适，说socket不如说tcp或udp等准确。因为从上文我们就可以看出socket只不过是一种标准的编程接口，除此之外并不代表什么，它的作用只是使编程风格统一化，使用统一的模型使用tcp等协议，实际上在调用时完全可以一端使用socket，而另一端使用ndis模拟协议实现，但是估计没有人会这么干，因为已经有现成的东西可用了。&lt;br /&gt;也就是说使用底层的驱动程序还有很多机制，例如本文说到的http.sys这也是使用底层协议的很好的例子。以后我可能会详细介绍ndis驱动模型，使用ndis可以模拟各种协议发送数据包。&lt;br /&gt;　　还要插一句：说一说我们常说的网络端口是什么？例如http常用的80端口，那么80到底是什么啊，看过tcp协议详解的同学会马上注意到端口的这种概念是出现在传输层的，IP层只涉及到IP地址为止，而传输层协议，例如tcp，udp等都会加入一个端口号，这其实是标准协议里规定的，实际上端口号在操作系统中只是一种标识，协议驱动程序会根据端口号和更详细的信息进行路由，例如我们说某个应用程序监听了80端口，那么驱动程序就会把协议中具有80端口的请求路由给这个监听程序。说白了就是一种标识，实现时也没有复杂的数据结构。当然这些概念都已经标准化了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.托管的HttpListener类型&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;HttpListener是一个.net的类型，可以使用它在.net平台下实现一个http的服务器，这个类型有很多成员，这个同学们可以参考msdn的相关文档，这也不是本文的重点。HttpListener实际上是基于httpapi.dll的，那么httpapi.dll是做什么的呢？我理解这个dll就是win32下对于http.sys核心态驱动程序功能的一个用户态的封装而已，使用httpapi.dll的导出函数，用户程序可以从用户态切换到到内核态使用http.sys，这就像kernel32.dll中的很多函数一样，实现了内核态系统服务的调用。那么有了这个用户带的dll就好办了。而HttpListener正是这个dll在.net平台下的封装，这样.net也可以间接的使用http.sys了。这也就为构建.net下的http服务器成为可能，因为这些基础性的东西微软已经为我们做好了。无论从理论还是实际上来看IIS6和HttpListener处理请求的性能是相当的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.如何寄宿ASP.NET运行时环境&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;观察IIS寄宿Asp.net的原理，我们会发现，真正的托管代码是从构建HttpWorkerRequest对象开始的，可以理解为IIS搜集了http请求的大量信息，之后构造了托管的HttpWorkerRequest对象，这个对象也就是托管和非托管的过度的关键，而后HttpWorkerRequest再去生成HttpContext对象，而这个HttpContext就是贯穿于Asp.net的pipeline模型始终的上下文对象。在.net进程中如何寄宿Asp.net的运行时呢？我们可以使用微软专门为寄宿Asp.net运行时而提供的的ApplicationHost类型（位于System.Web.Hosting）。System.Web.Hosting这个名称空间中有很多类型来处理其他种进程寄宿Asp.net运行时。代码类似：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('df07fd45-e5d8-4ac7-955b-3ff85633833c')"&gt;&lt;img style="display: none" id="code_img_opened_df07fd45-e5d8-4ac7-955b-3ff85633833c"  onclick="cnblogs_code_hide('df07fd45-e5d8-4ac7-955b-3ff85633833c',event)" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif"&gt; &#xD;
&lt;div id="cnblogs_code_open_df07fd45-e5d8-4ac7-955b-3ff85633833c" &gt;&#xD;
&lt;div&gt;&lt;!--&lt;br/ /&gt;&lt;br/ /&gt;Code highlighting produced by Actipro CodeHighlighter (freeware)&lt;br/ /&gt;http://www.CodeHighlighter.com/&lt;br/ /&gt;&lt;br/ /&gt;--&gt;&lt;span style="color: #0000ff"&gt;internal&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;AspxNetEngine(String&amp;nbsp;virtualAlias,&amp;nbsp;String&amp;nbsp;physicalDir)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_VirtualAlias&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;virtualAlias;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_PhysicalDirectory&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;physicalDir;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;Creating&amp;nbsp;a&amp;nbsp;new&amp;nbsp;AspxEngine.&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;m_ExecutingEngine&amp;nbsp;will&amp;nbsp;be&amp;nbsp;the&amp;nbsp;actual&amp;nbsp;object&amp;nbsp;that&amp;nbsp;the&amp;nbsp;hosting&amp;nbsp;API&amp;nbsp;created&amp;nbsp;for&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;us&amp;nbsp;and&amp;nbsp;so&amp;nbsp;to&amp;nbsp;execute&amp;nbsp;a&amp;nbsp;page&amp;nbsp;in&amp;nbsp;the&amp;nbsp;Application&amp;nbsp;we&amp;nbsp;will&amp;nbsp;call&amp;nbsp;this&amp;nbsp;object&amp;nbsp;to&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;process&amp;nbsp;requests&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_ExecutingAppDomain&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(AspxNetEngine)ApplicationHost.CreateApplicationHost(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000"&gt;(AspxNetEngine),&amp;nbsp;m_VirtualAlias,m_PhysicalDirectory);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Console.WriteLine(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;New&amp;nbsp;AspxEngine&amp;nbsp;created&amp;nbsp;for&amp;nbsp;alias&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;+&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;m_VirtualAlias);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;ApplicationHost.CreateApplicationHost方法会创建一个新的应用程序域，并AspxNetEngine作为应用程序域通信的对象，所以AspxNetEngine必须是MarshalByRefObject。&lt;/p&gt;&#xD;
&lt;p&gt;基于以上资料我们就完全可以使用托管代码实现一个简单寄宿Asp.net的运行时的环境，这里的说的&amp;#8220;简单&amp;#8221;主要是比起IIS还有一些性能问题和其他方面的问题，下文将详细说明遇到的相关问题。其实这种实现网上有很多种，例如classin或vs自带的开发服务器，这种东西应用到实际的生产环境还是有问题的，IIS我们轻易不能放弃。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Thriving-Country/aggbug/1789253.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Thriving-Country/archive/2010/07/31/1789253.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Thriving-Country/archive/2009/12/20/1628314.html</id><title type="text">【读书笔记】《框架设计（第2版）CLR Via C#》中两个比较有趣的知识点</title><summary type="text">在阅读这本书时我发现很多值得思考和有趣的地方，例如：JR关于调用的参数和返回值的建议；位索引器示例；触发事件的事件安全；字符串格式化和字符串的驻留等。尤其是.NET的垃圾回收机制在这本书中讲的很详细。其中有两个知识点是让我感到收获很大的地方而且例子也很详细，我在这里就单独拿出来与大家分享，同时也作为知识点进行总结，这里讲没什么技术含量，大家别BS我。</summary><published>2009-12-20T09:18:00Z</published><updated>2009-12-20T09:18:00Z</updated><author><name>GUO Xingwang</name><uri>http://www.cnblogs.com/Thriving-Country/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Thriving-Country/archive/2009/12/20/1628314.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Thriving-Country/archive/2009/12/20/1628314.html"/></entry></feed>
