thread & socket 的系統數量限制!?(300分)

J

jiichen

Unregistered / Unconfirmed
GUEST, unregistred user!
1. 想創建 10000 個 Thread ,但到達 27xx 個的時候,出現了 『thread creation error:
附加到系統的某個裝置失去作用』 或 『thread creation error: 儲存體空間不足』的
錯誤訊息,但此時記憶體空間還剩下很多,請問要如何讓其達到上萬個,甚至十萬個
的數量?
OS: Windows2000 Server ,RAM: 768 MB
2. 在上述 Thread 內想創建一組 TClientSocket ,但此時數量更少,只 3xx 個 Thread
創建便發生了錯誤,是否 Windows 有限制 socket 的數量?但一些可以容納上百萬人的
程式是如何做到的?

ps: 當出現上述錯誤時,便不能在執行其他程式了,一樣會跑出相同的錯誤訊息!
 
操作系统当然有线程总数的限制了,具体是多少确实不知道,但感觉上这种思路太疯狂了,
恐怕没有哪个系统支撑得起的。
Socket最大数也是一样,但可以在注册表中增大它,不过仍然受制于OS的资源。对于windows
来说,每个Socket都有Handle,所以每生成一个Socket,相当于生成一个窗口了,只是看不见
而已。
因此出现这样的错误时,任何程序都运行不了是正常的--系统满载了。
容纳上百万人的程序(我觉得应该是系统)不是想象的简单,它可能用了负载平衡,网络流量分配,
服务器负荷分担等相关技术,而且有一点是肯定的,数量少的服务器肯定不是面向连接的TCP,
一般用UDP通讯--比如DNS服务器。
 
呵呵,之所以會提問一來是最近的工作有些許關連,二來是最近在玩 p2p 軟體。
像 Kazaa ,可同時二三百萬人 online ,不過它沒有提供自己架設 SERVER 的功能,
所以跳過不談。
至於 eDonkey &
eMule 有提供自己架設 SERVER 的軟體,(它們兩個是同一套
Server 軟體),預設值最大是是 6000 個 Client,並且 9x 系列便可架設,
所以實在覺得疑惑,看了一下,也有同時 30000 人 online 的 Server ,是使用
TCP 的連接方式,(用 netstat -n 看的)。
如果是像特定伺服器,如 Unix 、 Linux 或 IBM xxx ,那我不覺得奇怪,但同樣是
Windows ,為什麼差這麼多??(我的第一個測試 ,Thread 很簡單就只有 Create ,
然後 sleep 直到 terminated 為止 。)
 
你的思路也许不对了,那些同时处理成百上千个个连接的服务器,大多不是创建成百上千个
线程实现的,而是使用更高效的socket管理的i/o机制,如完成端口(complete port)
 
可以詳述?
Delphi 有類似功能的元件嗎??
 
当要面对大量客户端访问时,虽然需要多服务器来分担负荷,但对于一台服务器来说,建立
上万个线程也是不可接受的。多线程虽然能够更充分地使用CPU,但在线程间切换时也是需要
占用CPU时间的,当线程过多时,光是用于为线程分配资料及线程切换所需要的CPU时间就超
过了多线程处理所能换来的时间,所以对于一个系统来说并不是线程越多越好的。
对于用多少个线程效率是最高的这个问题,我曾听是CPU数量X2,也有听说X8或X16的,我没
做过具体的测试,不知道哪种说法是正确的。我认为应根据具体情况来分析,如果一个任务
很简单,能在非常短的时间内完成,那么完成任务所需要的线程就可以较少(甚至单线程反
而是最快的——但这种情况在实际应用中可能不多),如果任务需要较长的时间来完成,比
如等待读写低速I/O的数据时,较多的线程可能效率会更好,但线程的数量不会是成千上万个。
在线游戏服务器的的大客户量并发服务程序前一段时间我们也研究过一段时间,买了几本参
考书,其中一本电子工业出版社的TCP/IP客户机-服务器编程中谈了较多的实现技术(但其中
没有代码),对于线程管理的技术是采用线程池,即先建立一定数量的线程,处理完一个任
务后并不立即退出,而是将它放在池中,主线程在accept到客户端连接请求后,就把后面的
处理交给池中一个空闲的线程来做,这样才是提高处理效率最佳的办法。在W.Richard Stevnes
著的《UNIX Network Programming》一书中有基于Berkeley Socket API的基于线程池的例程。
(Windows Socket就是从Berkely Socket移植过来的)
 
你的情况遇到过,thread creation error: 儲存體空間不足
我的做法是这样,先把所有的thread create(true)起来,放到一个list表里,并且create时suspend=true的,
然后一次在list中resume所有的thread.这样作create得快,你可以比较一下。 另外还有一点:create的时候把propity设为tpidle,否则你的程序
死掉的。
 
在WINDOWS下用完成端口和重叠I/O可以一个线程提供多个连接,可以避免这个问题
具体的是用acceptex来处理,
 
但是想提高效率就用API写,不要用VCL恐件,最多就用Thread类,
 
http://www.csdn.net/Develop/article/15%5C15211.shtm
 
用UDP的时候
是不是不应该在接收数据后就进行数据的业务处理,这样会丢掉一些数据包?
比如:根据发送来的数据, 下载数据请求 应该创建一个线程来完成这个操作,是吧!
 
1000个线程应该没有问题把,但是有的书籍say单个cpu*25个,我靠,启动一个win2000server
就不只这么多。
 
顺带问一下,谁知道window98 socket端口数,为什么我上到八十几个的 socket端口数时就提示端口不足。(不是采用多线程,而是旁门左道的)
多线程下载,delphi 6.0 Tclientsocket控件,非阻塞。
程序的CPU占有率不是很高,请各位大侠指点。
 
顶部