彭斌

[ 2006,2007 ASP.NET ' MVP ]
随笔 - 99, 文章 - 5, 评论 - 1027, 引用 - 16
数据加载中……

Community Server专题附录一: 什么是Threads & Processes

 

Community Server专题附录一: 什么是Threads & Processes

 

请用批判的眼光来看下面的文字:

线程和进程(Threads and Processes) 简单说,你启动一个程序,就启动了一个进程,早期win3.x的系统以进程为单位(嘿嘿,其实我没有用过win3.x),win98后每个进程还可以启动几个线程,因此以线程为单位。在如今的操作系统下线程间是独立运行的,但是他们共享一些内存中的片断,如:全局变量等。

问题来了:CS在服务器上运行是多线程的吗?每个用户的Http请求CS做了什么?CS系统在被第一次访问的时候由asp.net运行机制启动一个CS进程,启动进程是需要给该进程分配独立的内存地址的,该地址不受其他的进程影响和操作。也就是说如果你还有其他的Web程序是无法访问这段内存空间的(正常情况下进程与进程之间是安全的)。有了CS的进程还不够,前面说过win98后的操作系统执行的最小单元时线程而不是进程。因此接下来会为这个请求启动一个线程(对于web程序来说,Http请求的线程启动过程不需要你使用System.Threading命名空间下的方法,启动的过程右asp.net运行机制完成),由于一个进程的所有线程都共享它的内存地址空间、全局变量和操作系统资源,因此这个请求可以根据共享的资源为自己建立一个上下文Context,然后处理相关的请求操作,请求完成后线程会被释放,他的生存周期也就结束了(因此说Http请求是无状态的,因为同一个用户的两次Http请求会建立两个不同的线程,他们的Context是不同的,而且有前后顺序。但是为了保存一些必要的状态信息因此有了CookiesSession)。当有第二个http请求发出的时候,很有可能第一个http请求还没有处理完成,因此这里就牵涉到了多线程执行下的线程安全问题。

线程安全,是指一个方法(method)可以在多线程的环境下安全的有效的访问进程级的数据(这些数据是与其他线程共享的)。要保证线程安全关键是同步,保证多个线程同时开始执行,并行运行、不同时访问相同的对象实例、不同时执行同一段代码,.net下我们可以通过一些手段来保证我们的数据是安全的,如采用System.Threading.Monitor加锁以确保对共享数据访问的同步性。其实在MSDN中我经常都会看到对一个方法介绍时候都会加以说明该方法是Thread Safe,也就是线程安全的。线程安全是一个高级议题,不能再往下说了,不然就见底了。

其实只要不重新启动IIS那么CS的进程就一直存在,而且只有一个。但是CS的线程就多了,根据不同的Http请求会有多个线程,同时CS中还使用了Timer,它也会启动新的处理线程,该线程的生命周期一直持续到TimerDispose

可以看出CS是一个复杂的多线程程序,当然所有的web app都是多线程的,因此分析之前很有必要了解线程与进程的概念

posted on 2005-09-15 10:47 彭斌 阅读(3952) 评论(12)  编辑 收藏 所属分类: CommunityServer

评论

#1楼   回复  引用    

这也是我所担心的,确实每一个HTTP请求,WEB服务器就启动一个线程,其结果是如果同时有成千上万个用户请求,web服务器就要启用成千上万个线程。
有人说Community server的最大局限性就是用户数,当超过100个用户同时访问时,其性能显著下降。
我一致也不明白想sohu,sina等网站怎么做成的,他们的扩展名都是shtml,感觉用的是linux系统,而且是apache服务器。可能是用代码生成HTML页面,毕竟那种页面效率最高
2005-09-15 11:24 | PPP[未注册用户]

#2楼[楼主]   回复  引用  查看    

其实硬件的投入远远小于软件的投入,如果一个能在同一时间执行100线程的web站点,那么该站点的日访问了可能要用十万甚至更高的数量级来计算。其实如DVBBS等系统也是非常耗费系统资源的,他的在线人数不是指并发的线程数,而是在一定时间内访问的人数(如15分钟内访问的所有IP地址数就是他所谓的在线人数)。
大型门户网站都采用的静态页面(通过某种系统生成html页面),对这个页面的请求通过IIS发送数据流就可以,不需要做一些动态处理(比如调用数据库什么的),另外大型网站都是服务器群部署的。
2005-09-15 11:43 | uGoer      

#3楼   回复  引用  查看    

sohu,sina 的新闻都是用Squid做的透明代理,nslookup 可看出有多个IP,至于多个IP后面还肯定有多台服务区。shtml学名是SSI,IIS、Apache都支持,于普通HTML不同,他支持include file等简单语句,又不向ASP/JSP等需要大量的解析工作,因此效率很高。sohu上使用shtml而不是html我估计是考虑到万一更改一下网页的头和尾那么重新生成成千上万的页面代价太高~,使用shtml include 头尾,只要修改头尾文件就行了 。加上squid的透明代理,就可以方便的做到同步更新数据、负载,头尾修改了,只要清空squid的缓存文件就可以。(squid 可以说是效率最好的透明代理了,支持缓存、设置扩展名多域名等等)。

至于多进程多线程,条件允许我觉得做成与WEB辅助工作的WINDOWS服务会好些,IIS也会稳定好多,性能也有提升。不过CS这样公开发布的APP肯定要满足尽量多的人,不能做特定优化。
2005-09-15 12:34 | flower.b      

#4楼   回复  引用    

这也是我所担心的,确实每一个HTTP请求,WEB服务器就启动一个线程,其结果是如果同时有成千上万个用户请求,web服务器就要启用成千上万个线程。

-设计如此原始的web 服务器现如今也不是这么容易找到了吧
2005-09-15 13:08 | rIPPER[未注册用户]

#5楼   回复  引用  查看    

“因为同一个用户的两次Http请求会建立两个不同的线程,他们的Context是不同的”
这句话是错误的,两个请求的context不同完全是一种人为的隔离,并不是由于两个线程的原因。如果需要的话,完全可以在两个线程之间共享一个context,也可以在用户请求完毕后保留这个context。但是这样做一般没有意义,因为http连接是非持续性的。
关于web服务器的结构可以参考一下tomcat,其他的服务器都大同小异。
tomcat为每一个请求启动一个线程,tomcat设置了3个线程数:最少线程数(默认为5,服务器启动后就有5个线程等待请求,避免临时启动线程影响效率)、最大线程数(默认为75,最多使用这么多线程处理请求,再来请求先不处理,让他们等待)、最大处理的请求数(默认为100,超过那么多请求就不再等待,直接向他们返回服务器忙的错误)
2005-09-15 17:02 | 小陆      

#6楼[楼主]   回复  引用  查看    

批评的眼光终于来了
@小陆
context是线程执行需要的或者得到的信息,保存在寄存器(register),不同的线程之间可以共享信息,但是.Net为了线程安全,不允许同步操作一个数据。
如果你要证明“因为同一个用户的两次Http请求会建立两个不同的线程,他们的Context是不同的” 这句话是错误的,必须给出两个请求或者多个请求使用一个线程的理由来,不然这话还是成立的,指教了。

2005-09-15 17:53 | uGoer      

#7楼   回复  引用  查看    

处理一些静态内容的时候,比如http请求html或者gif文件的时候,为一个请求建立一个线程是一种开销比较大的方式。通常在建设一个负载很重的jsp站点的时候,可以先建立一个apache web server,然后将tomcat作为apache的一个组件,专门负责应对jsp请求,一般的静态内容由apache负责。这就是由于apache在静态内容的处理上优于tomcat。tomcat使用的就是为一个请求建立一个线程的方式。

在某些server里面采用多线程处理多个请求的方式,比如iis smtp service是这样工作的:当一个请求到来的时候,请求socket通信采用一个独立的线程,这个线程只负责从socket上不断的接受请求,接受之后就将他交给后面的线程。后面的线程处理这个请求的时候,也不是只用一个独立的线程,而是采用多个线程,每个线程只处理其中的一段过程。最后这个请求处理完毕,交给一个独立的线程从socket端口送回客户端。

这样的情景就类似于很多人搬一堆石头,不是让这些人都去进行搬运的整个过程,而是让这些人站成一排,互相传递着搬。这样的好处是,每个线程只运行很少的一段指令,有利于cpu命中缓存,大大提高了速度,可以处理大量的并发请求。

在这样的情况下,线程之间自然也就是共享context的了。
2005-09-16 09:01 | 小陆      

#8楼[楼主]   回复  引用  查看    

@小陆
IIS下对请求html或者gif文件的时候,如果没有做这些文件到asp.net运行机制的映射,这些请求由IIS去完成,而asp.net根本不知道这个请求过程,这有点像你说的apache与tomcat的关系。在IIS 6.0中对静内容和页面的请求有时会共享一个处理线程。
由于对CS的每个页面请求都是对*.aspx的请求,所以我表述为每个请求都会建立一个线程,这是线程是由ASP.NET运行机制建立的,不是由IIS建立的。请继续指教。
2005-09-16 11:22 | uGoer      

#9楼   回复  引用  查看    

如果具体的说asp.net或者jsp,那么每请求一个线程,每线程一个context是正确的。
因为这两种service处理的都是动态的内容,因此这样的方式是十分清晰简洁的。采用共享context的方式会大大增加复杂性,并且影响service的功能扩展,得不偿失。
一开始没有搞明白文章是在说一个具体的产品,sorry。
2005-09-16 12:40 | 小陆      

#10楼   回复  引用    

msdn中AppDomain的概念:
多个应用程序域可以在一个进程中运行;但是,在应用程序域和线程之间没有一对一的关联。多个线程可以属于一个应用程序域,尽管给定的线程并不局限于一个应用程序域,但在任何给定时间,线程都在一个应用程序域中执行。

应用程序域提供安全而通用的处理单元,公共语言运行库可使用它来提供应用程序之间的隔离。您可以在具有同等隔离级别(存在于单独的进程中)的单个进程中运行几个应用程序域,而不会造成进程间调用或进程间切换等方面的额外开销。在一个进程内运行多个应用程序的能力显著增强了服务器的可伸缩性。

CS自然就是这样一个AppDomain,其实CS这个Asp.Net的AppDomain就是aspnet_isapi.dll进程的一个“特殊线程”(处理单元,公共语言运行库可使用它来提供应用程序之间的隔离),一个进程中运行多个线程来提高吞吐率是很有效也比较常用的思想,没错context(HttpContext.Current)请求就是一个线程,AppDomain能保证“在任何给定时间,线程都在一个应用程序域中执行”
2005-09-27 11:11 | microhf[未注册用户]

#11楼   回复  引用  查看    

应该说,不会为CS建立一个进程,而是为aspnet_wp.dll建立一个进程,CS只会建立一个AppDomain。
2005-12-07 14:31 | THIN      

#12楼   回复  引用    

我非常想用 CS系列跑一个大型应用,但是朋友跟我说 CS在人数上有缺陷,

正如楼主说的硬件不值钱,请教CS系列可以分布式发布吗?
2006-06-06 18:27 | hobowang[未注册用户]



发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 237412


相关文章:

相关链接: