bh3531 发表于 2014-04-01 10:57

新手遇到 threading 内存占用大的问题

请教 大家一个问题
while True:
    data,addr = sock.recvfrom(1024)
    threading.Timer(0,Check_data,).start()


这样做会导致内存占用很大 ,
但是如果修改成 :
while True:
    data,addr = sock.recvfrom(1024)
    Check_data(data)
内存 和 初始值一样,不知道谁能帮忙看一下



我的SOCKET 并发很多,所以需要使用多线程来解决 并发写文件,但是使用 threading 会使内存占用到 50M 。
如果 不使用 threading 内存占用 只有5M ,但是会导致信息写文件不全,原因是 还没有写完文件 又来的新的消息,所以需要使用 threading。

为了测试是不是 Check_data 函数有什么问题,我就做了测试 ,Check_data只做 print ,结果还是那样,希望有哥哥帮忙新手解答一下。

def Check_data(data):
    print data

timespace 发表于 2014-04-01 11:18

回复 1# bh3531
不奇怪, “while True”里面加入threading.Timer线程,没把机器搞死算你走运。
每个Timer都是一个独立的线程,如果读取数据比较多且Timer执行较慢,意味着每个时间点有很多Timer并存,在Linux/UNIX下,线程栈大小默认就是8MB或10MB,所以占个几十MB内存很正常。


   

timespace 发表于 2014-04-01 11:29

再补充一点,这是程序设计的问题,实践中网络IO的数据流量很少超过本地磁盘的IO性能,只要线程职责分配到位,不会有什么瓶颈。
下面是一种简单而通用的做法,多占内存是正常的,空间换取时间嘛,当然不能无谓的占用内存,像上面很多Timer就会占用无谓的内存:
线程A: 读取UDP端口数据,放入队列中
线程B,读取队列的数据,写入本地文件中

bh3531 发表于 2014-04-01 11:40

回复 3# timespace


    我有想过这样做,但是我想的似乎不通, UDP 信息收到后 放到 队列中,然后用另外一个函数去读取队列,这时候 就要使用 锁。
如果 该队列变量正在 被读取, socket 拿不到锁 就会一直等待,这时候 就有可能 在等待拿锁的时候 有其他新消息 没有接受到。

可能是我的思路没有想通,麻烦你 再描述一下 ,谢谢了

timespace 发表于 2014-04-01 12:10

回复 4# bh3531
思路没问题,只是低估了锁的效率,多线程哪有不用锁的时候?但是锁通常只有几微妙的延迟,(加锁-数据入队列-解锁)总时间比你创建Timer都要快,更是比网络IO快几个数量级。说多少都不如手动试下,没什么复杂度。


   

timespace 发表于 2014-04-01 12:27

还有,UDP做服务端,保证有足够大的接收缓存区(socke.setsockopt控制),如此会对流量波动有好的容错能力,尤其是多个客户端同时发包。
页: [1]
查看完整版本: 新手遇到 threading 内存占用大的问题