【发布时间】: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()
任何人的意见都将受到高度赞赏。
【问题讨论】:
-
嗨 Gphilo,我分享了代码 sn-p。请提供任何见解。
标签: python multithreading memory-leaks queue