LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1031|回复: 11

多线程的问题。

[复制链接]
发表于 2005-3-4 21:01:22 | 显示全部楼层 |阅读模式
我的主线程监听网络,
有客户请求时生成一个线程并发送一个文件,
文件比较大,需要一定时间。

当同时存在几个客户时,
由于每个线程都在传输文件,
所以CPU的占用率100%。

可是BT、flashget这些软件在使用时,
CPU占用率才30%左右。

这是怎么回事?
发表于 2005-3-5 00:35:13 | 显示全部楼层
你需要在你的主线程的while循环里面,生成一个新的thread后,加一句Thread.sleep(X),就是让你的工作线程"睡"上一些时间,以便其他的程序可以有时间工作。试试看这样是不是就不会占用cpu 100%的时间了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-5 08:52:46 | 显示全部楼层
我的子线程是向客户传输数据的,
所以,
我main线程创造的子线程都需要工作,
不能让他们sleep。

补充一句:
我的主线程采用ServerSocket,
使用
while(true){
      ServerSocket对象.accept();
      new SubThread().start();
      ……
}
所以每生成一个子线程后,
它都会回到accept方法阻塞,等待下一个请求,
所以不用sleep掉主线程。

另:
我的所有子线程都在在正常工作,
不用sleep主线程,也可以启动子线程,
因为生成子线程后,子线程就是“就绪状态”,
由操作系统调度它的状态。
回复 支持 反对

使用道具 举报

发表于 2005-3-5 10:52:12 | 显示全部楼层
程序正常运行是不用sleep,但是你如果不在你的while(true)里面sleep一下,就一直cpu 100%,所以应适当的sleep一点儿时间,给其他程序运行的机会,这样就不会cp占用率总是100%啦。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-5 11:15:03 | 显示全部楼层
我终于知道您要告诉我什么了,
如果没理解错的话:

比如有10个子线程在向客户传输数据,
每个子线程在传输一部分数据后,
(不能一直传输结束,否则占用cpu的时间过长)
sleep一下,
以便让其他刚醒来的子线程完成自己该传输的那一部分。

也就是说,
宏观上,cpu每次只是在调度2个或3个的子线程,
可能会更少,因为别人睡着了,反正比10个少很多,
这样不仅是每个子线程都能工作,
同时还可以利用有限的cpu资源。

这样会不会出现:
大家多数一起睡觉,
然后多数线程又一起工作,
因为不能保证睡觉的线程是9个还是1个,
造成cpu占用率时而很低,时而100%的现象?
回复 支持 反对

使用道具 举报

发表于 2005-3-5 11:28:12 | 显示全部楼层
我想如果你的工作线程工作量不是很大的话,应该不需要sleep,但是你的那个创建工作线程的主线程,就是那个我说的while(true)循环,来接受client socket请求的线程,一定需要sleep,你可以先这样试试看。
如果你的工作线程工作量很大,就像你说的要传输mp3文件之类的,我想这个线程中间可能也需要sleep一下,这一点我不是非常确定。
你可以先在主线程里面接受到client的请求,开始下一个等待的之前,sleep一下,这个我想是必须的。如果cpu还是100%,那么就需要看看是否在工作线程里面也需要sleep一下,就像分片传送一样,或者说一次不能传送太大的报文,而是把文件分段传送,我想bt好像也是这样的吧:-)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-5 13:07:38 | 显示全部楼层
哦!!!!
哈哈……

您提到了BT,
这回您可说到点上了,
我就是在作类似这个东西的P2P软件(这是毕业设计),
不过,我用的是JXTA。

我在得到其他端点传来的数据后,
先分辨这是"请求"还是"响应",
如果是请求,
就要建立一个额外的线程去传输数据,
您提到sleep,我想子线程也要sleep,因为文件很大,有的上百M或几个G。

您又提到分段传输,
我也想到了,
按照BT协议规定,
块的大小为32K、64K、128K……1024K,不等,
如果每个子线程传输一个块(最大也就1024K),
这样在子线程里就不用sleep了吧?
回复 支持 反对

使用道具 举报

发表于 2005-3-5 13:20:27 | 显示全部楼层
不错,你的毕业设计方向比较新颖,应该是计算机系的吧,如果你做好了,也可以让大家用一下:-)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-3-5 15:11:09 | 显示全部楼层
使用了您的“睡觉方式”,
效果显著!

很显然您的实际经验比较丰富,
而我就差远了,
以后还要向您多学习学习。

追加一个问题:
首先,我的主线程只有在有数据传来时,
才会响应,一般情况下,一直是阻塞的,
只有子线程需要“睡觉”来缓解cpu的负担。

我有5个子线程,
每个子线程的工作负担不同,
按照块的大小,分为32K到1024K不等,
即,上传工作用时为1s到20几秒不等(512K/S ADSL),
那么,根据什么来决定“睡觉”的时间呢?

如果睡得太长,
显得效率不高,
如果睡得太短,
cpu的占用率又高了。

这可如何是好?
回复 支持 反对

使用道具 举报

发表于 2005-3-5 18:28:49 | 显示全部楼层
今天看过你的问题以后,我去看了看tomcat 4.1.30的source,看了看它是怎么处理的。基本上看懂了它的socket处理机制,它不是用简单的sleep来做的,因为如果那样估计也会碰到你上面的问题。它是采用java线程控制中的wait和notify机制,就是如果工作线程(就是下面的HttpConnector)没有活就wait,这样就不会占用cpu,而如果一旦serversocket接受到http请求就立即notify等待的工作线程,让其处理这个请求,处理完以后接着wait。当然它做的比较复杂,还有一个HttpConnector的pool。
你有兴趣的话,可以下载tomcat的source包看看这2个类
org/apache/catalina/connector/http/HttpConnector
org/apache/catalina/connector/http/HttpProcessor
如果看这个代码的时候有什么问题我们可以探讨一下,我想这段程序应该对你写这个p2p程序有用。
不知楼主有没有兴趣看看?我将这2个类附在后面了,方便你去研究,如果你认为这2个类,信息或者上下文不够,可以自己下载tomcat的完整源码:-)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表