【问题标题】:Threading in python and Queue leads to memory leak or memory errorpython和Queue中的线程导致内存泄漏或内存错误
【发布时间】:2020-03-09 13:04:50
【问题描述】:

我在 python 中使用多线程和队列创建了简单的代码。我有一个主线程不断在队列中添加数据(队列最大大小为 2000),并且将有 5 个不同的线程从队列中取出并在某个特定通道发布到 redis。

代码运行良好,但 5 或 6 小时后,发布机制变得缓慢。 随着用于从队列中删除数据的线程变慢,并开始抛出缓冲区溢出错误,队列大小达到最大大小。将数据加入队列的速度与开始时相同。

在不同配置的 Linux 系统上会出现不同的问题。如何识别它抛出了什么样的错误?如何调试问题。

如前所述,代码非常简单,主线程需要将数据一个一个加入队列,其他5个线程一个一个将数据从队列中取出。

分享代码

   import redis
   import logging
   import sys
   logging.basicConfig(level = logging.DEBUG)
   redisPub = redis.StrictRedis(host='127.0.0.1', port=6379)

def main():
    try:
        recv_sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
        recv_sock.bind(("", 8000))
        recv_sock.setblocking(0)
        recv_sock.settimeout(5)
    except Exception,e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        logging.error("Socket Connection Unsuccessful")
        print "Program halted."
        sys.exit()

    sendThEvent     = threading.Event()
    sendThEvent.clear()
    sendPktQ = Queue.Queue(maxsize=2000)
    for i in range(0,5):
        thSend = threading.Thread(name = 'sendThread', target = sendThread , args = (sendPktQ,sendThEvent))
        thSend.setDaemon(True)
        thSend.start()

    packetsCounting = 0
    while True:
        try:
            recvData, recvAddr = recv_sock.recvfrom(2048)
            sendPktQ.put(recvData)
            packetsCounting += 1

            else:
                logging.error("There is some error")
        except socket.timeout:
            continue
        except Exception,e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            logging.error(e)



def sendThread(sendPktQ,listenEvent):
    if sendPktQ == None:
        pass
    else:
        while True:
            instanceSentCnt += 1
            if sendPktQ.qsize() < 1:
                event_is_set = listenEvent.wait(0)

            packetDict = sendPktQ.get()
            data = redisPub.publish('chnlName', packetToSend)
            logging.info("packet size reached to ============================================ %s ------------ %s"%(len(packetToSend),data))



if __name__ == "__main__":
    main()

任何人的意见都将受到高度赞赏。

【问题讨论】:

标签: python multithreading memory-leaks queue


【解决方案1】:

我看到sendPktQ.get(),但没有看到sendPktQ.task_done(),例如:

async def _dispatch_packet(self, destination=None) -> None:
    """Send a command unless in listen_only mode."""
    if not self.command_queue.empty():
        cmd = self.command_queue.get()

        if not (destination is None or self.config.get("listen_only")):
            destination.write(bytearray(f"{cmd}\r\n".encode("ascii")))
            await asyncio.sleep(0.05)

        self.command_queue.task_done()

queue library docs

【讨论】:

    猜你喜欢
    • 2014-03-24
    • 1970-01-01
    • 2022-11-06
    • 2011-09-23
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多