Chinaunix

标题: 请问pyhon开多线程费内存吗 [打印本页]

作者: fandatou    时间: 2006-03-22 15:50
标题: 请问pyhon开多线程费内存吗
我写了一个验证代理服务器匿名程度的perl脚本,开了5个线程去访问被测页面。脚本一开60M内存没了,检测完358个代理服务器后,内存占用高达200M。我就开了5个线程为啥么perl多线程这么废内存。

过几天我要写一个9线程脚本,每个线程要连续访问499个页面并处理信息,请问诸位高手pyhton多线程处理能力如何,内存使用情况如何?是否稳定?
作者: bleem1998    时间: 2006-03-22 23:25


[ 本帖最后由 bleem1998 于 2006-12-11 13:01 编辑 ]
作者: fandatou    时间: 2006-03-28 14:20
不是说perl坏话,我的程序大部分都是perl的。我现在处理22个服务器的信息,还有100多台服务器的信息没弄呢,必须为将来考虑。
作者: Rcfeng    时间: 2006-03-29 13:51
提示: 作者被禁止或删除 内容自动屏蔽
作者: xichen    时间: 2006-04-03 16:50
我开过30个线程的程序,内存占用大约10M左右吧,我想这个还是和程序有关的.
另外perl应该没有这么离谱,多线程和多进程是不一样的.
作者: fandatou    时间: 2006-11-12 19:00
哈哈,把程序修改为30线程的,内存直接奔1G去了。
作者: assiss    时间: 2006-11-12 21:18
也太恐怖了吧。
如果只是简单的测试代理页面,绝对不会用到这么多内存的。

线程本身并不占用多少内存,占用内存的是线程里的应用。

就算是对访问页面的复杂应用,把所需页面全面加载到内存,每个页面也不过几百K吧。
就算PYTHON的自动管理内存没起作用,几百K×500页面,也不会到1个G吧。

楼主是不是调用了其它耗内存的函数?
作者: awake    时间: 2006-11-13 14:11
Python的线程应该比Perl的好些吧。Perl的线程还从来没用过。事实上线程不好用你可以改用进程嘛。
作者: ghostwwl    时间: 2006-11-13 14:17
python的线程 相对于 perl的要成熟些  而且python的线程直接来源 自 久经考验 的 pthread库

[ 本帖最后由 ghostwwl 于 2006-11-14 19:09 编辑 ]
作者: fandatou    时间: 2006-11-13 23:36
每干啥,就是抓下来网页用正则把需要的数据取下来。刚修改了下程序,不指定每次线程启动数,程序效率提升不少,从33/分钟 提升到50个/分钟. 内存就剩下1008k。

我的程序就是单线程也一样运行时间长了就会占用很大内存,不知道为啥perl不自己清理吓
作者: aaronvox    时间: 2006-11-14 13:53
原帖由 fandatou 于 2006-11-13 23:36 发表
每干啥,就是抓下来网页用正则把需要的数据取下来。刚修改了下程序,不指定每次线程启动数,程序效率提升不少,从33/分钟 提升到50个/分钟. 内存就剩下1008k。

我的程序就是单线程也一样运行时间长了就会占用很 ...



时间长了就会占用很大内存??
检查下是不是没有释放什么变量致使持续变大
据我所知perl里定义个ref,undef后不会释放内存,但是新生成的ref会利用原undef的内存
所以如果不是持续抢占地盘应该没有那么夸张
等待flw出现...
作者: assiss    时间: 2006-11-14 17:14
那有可能是你的垃圾回收管理真的没起作用……
不过这样的可能性不太大。

PYTHON的垃圾回收机制似乎是根据数量来定的,到达一定数量后启动gc.collect()
这也许是为了效率。

这就造成了使用pygtk时gtk.gdk.pixbuf的困惑:pixbuf每个都可能占用数MB甚至数十MB的内存,十个PIXBUF就有可能把内存耗光。而10个PIXBUF被DEL的时候,gc.collect()一般是不会自动启动的,需要手工调用。
作者: fandatou    时间: 2006-12-10 16:45
经过测试python不费内存,程序跑起来只有了41M内存,其中包含一个9M的 list,CPU倒是一直100%
跟我的perl倒是相得益彰,一个用内存一个用cpu,各取所需
作者: flw    时间: 2006-12-11 12:45
blem* 同学,请不要诽谤,编辑一下你的发言。
作者: bleem1998    时间: 2006-12-11 12:54
原帖由 flw 于 2006-12-11 12:45 发表
blem* 同学,请不要诽谤,编辑一下你的发言。


'bleem1998'貌似不匹配'blem*'
看来不是说我

作者: flw    时间: 2006-12-11 12:58
原帖由 bleem1998 于 2006-12-11 12:54 发表

'bleem1998'貌似不匹配'blem*'
看来不是说我

请你编辑一下你的发言,谢谢。
作者: bleem1998    时间: 2006-12-11 13:01
好吧
看在你是技术大牛MM的份上
作者: flw    时间: 2006-12-11 13:13
原帖由 bleem1998 于 2006-12-11 13:01 发表
好吧
看在你是技术大牛MM的份上

感谢。
作者: fandatou    时间: 2006-12-11 14:59
近来看到google用的python写的爬虫,一台机器能维护300个线程,我这里5个线程就cpu100%了。为啥呢?笔记本是迅驰1.4的 server是志强2G +2M 的 都是100%
作者: limodou    时间: 2006-12-11 15:13
在循环中加入些等待的处理,不然会一直占用的。
作者: fandatou    时间: 2006-12-11 15:21
不明白,我就是开5个线程去抓网页,抓下来后正则分解写数据库,然后返回。
作者: ghostwwl    时间: 2006-12-12 17:33
木头说得对,不然你有的链接有问题,那个线程死在那里占着cpu不放
作者: fandatou    时间: 2006-12-14 01:07
抓网页和写数据库都用try包围起来了。跑一些比较快的网站也cpu也是很高,回头弄个本地webserver试试看看开300个线程如何。
作者: phpbird    时间: 2006-12-15 22:16
应该是你写的程序的问题。
贴出来看看

[ 本帖最后由 phpbird 于 2006-12-15 22:18 编辑 ]
作者: shhgs    时间: 2006-12-19 13:48
不知道Perl的线程是怎么回事,不过Py的线程,我只是说线程,不会占用那么多的内存。但是如果你用线程递归计算Hanoi塔,那么占用100G,我也不会觉得奇怪。

Py的线程是混合线程。所谓混合线程是指,就OS的角度看,Py解释器只有一个线程,所谓Python的多线程,实际上是解释器水平实现的。因此多核CPU,SMP之类的,对Py来说是白费劲。但是,Py的多线程也并不是完全没有例外。block的IO的时候,解释器就是以多线程方式运行的。
作者: shhgs    时间: 2006-12-19 13:57
估计是gabbage网页占了内存空间。

Py的垃圾回收机制和Java的有点类似。只要还有内存,他就不回收。所以用得多也正常。

我倒是从来不做垃圾回收。不知道gc.collect是不是能起作用。
作者: 星尘细雨    时间: 2006-12-19 21:31
5个程序占用100%, 开300个不一样占100%嘛。。。
作者: fandatou    时间: 2006-12-19 23:41
抓网站的代码在这里
  1. def openurl(id):
  2.     url ="""http://""" + str(id) + """.xxx.com"""
  3.     print url
  4.     try:
  5.         html_date = urllib.urlopen(url).read()
  6.         #print html_date
  7.     except:
  8.         print 'find a error'
  9.         pass
  10.     else:
  11.         logfile='log/' + str(id) +".html"
  12.         open(logfile,'w').write(html_date)
  13.         error_re=re.compile(r"""(数据库暂时没有您要查找的数据)""")
  14.         companyinfo_re=re.compile(r"""<font style="font-size:12pt">(.*?)</font>""", re.S|re.M)
  15.         Mobile_re=re.compile(r"<td align=center>手机:</td>.*?<td align=center>(.*?)</td>", re.S|re.M)
  16.         Fax_re=re.compile(r"<td align=center>传真:</td>.*?<td align=center>(.*?)</td>", re.S|re.M)
  17.         clear_re= re.compile( r"(<.*?>|&nbsp;|\s+|\n|\t|\r|\\|/|')")
  18.         info_re=re.compile(r"(企业类型|.....|管理体系认证):</b></td>.*?<t.*?>(.*?)</td>", re.S|re.M)
  19.         db_user = ""
  20.         db_pw = ""
  21.         db = MySQLdb.connect("localhost", db_user, db_pw ,"。。。")
  22.         c = db.cursor()
  23.         if error_re.search(html_date):
  24.             print "数据库暂时没有您要查找的数据"
  25.             open('error.log','a').writelines(str(id)+"\n")
  26.             return
  27.         try:
  28.             
  29.             if info_re.finditer(html_date):
  30.                 companyinfo_group=companyinfo_re.search(html_date)
  31.                 temp_info=companyinfo_group.groups()[0]
  32.                 company_info=clear_re.sub('',temp_info)
  33.                 mobile_group=Mobile_re.search(html_date)
  34.                 mobile=clear_re.sub('',mobile_group.groups()[0])
  35.                 print mobile
  36.                 Fax_group=Fax_re.search(html_date)
  37.                 Fax=clear_re.sub('',Fax_group.groups()[0])
  38.                 print Fax
  39.                 company_dict={"":""}
  40.                 for m in info_re.finditer(html_date):
  41.                     info_cat=m.groups()[0]
  42.                     name=clear_re.sub('',m.groups()[1])
  43.                     company_dict[info_cat]=name
  44.                     print "%s %s %s " % (info_cat , "," ,name)
  45.                    insert_data="insert  into company (Company_ID.....) values ('" + str(id) + "' ..... +"')"
  46.                 c.execute(insert_data)
  47.                 open('work.log','a').writelines(str(id)+"\n")
  48.                 return
  49.             else:
  50.                 print "open url error"
  51.                 open('error.log','a').writelines(str(id)+"\n")
  52.                 return
  53.             
  54.         except:
  55.             print "数据有错误"
  56.             open('error.log','a').writelines(str(id)+"\n")
  57.             return

  58.             
  59.     #print url
复制代码

[ 本帖最后由 fandatou 于 2006-12-19 23:43 编辑 ]
作者: mslk    时间: 2007-08-22 22:29
标题: 原因是perl的线程内存没有释放
原因是perl的线程内存一直没有释放,所以内存占得很多
可以加上new thread->(...)->join()或者new thread(...)->detach()
作者: fandatou    时间: 2007-09-02 18:26
嘻嘻,perl费内存,python的费点cpu,同样的程序写了2个版本的,2.4Gcpu和2
G内存物尽其用
作者: ybeetle    时间: 2007-09-05 13:14
提示: 作者被禁止或删除 内容自动屏蔽
作者: xichen    时间: 2007-09-05 23:20
如果你不想释放数据库,那把数据库拿出来,做全局看看.
另外,检查你多线程的部分.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2