使用Python Select()接收数据的显着延迟

时间:2017-04-20 13:06:53

标签: python multithreading sockets delay

我有一个Python脚本,用于从播放音频的机器接收与广播电台音频事件(如歌曲或商业广告)相关的数据。该脚本将解析并处理数据,然后将其中的一部分发送到其他各个目的地。

首先设置套接字:

client_socket_1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
    print 'trying to open socket 1'
    client_socket_1.connect((TCP_RCV_IP_CR1, TCP_RCV_PORT_CR1))
    client_socket_1.setblocking(0)
except socket.error, e:
    print 'Error', e, TCP_RCV_IP_CR1, '\n\n\n'
else:
    SOCK1 = 1
    print 'Successful connection to ',TCP_RCV_IP_CR1,'\n'

现在我们等到数据可供读取。我使用了select(),当套接字准备好被读取时,产生了解析和处理数据的线程。

ready_1 = select.select([client_socket_1], [], [], 1)   # select tells us when data is available at the socket
if ready_1[0] and SOCK1:        # Don't run this code if there is no connection on client_socket_1 or no data available
    t1 = Thread(target=processdata1)    # Set up the thread
    t1.start()  # Call the process to process available data as a thread

尽可能快地读取数据非常重要,因为它将通过TCP或UDP(取决于特定数据块和程序规范)以及相关音频以及其中一个数据项的功能进行传输如果没有及时收到,我们正在处理可以在音频中创建播出“打嗝”。 (TMI:它会在接收端播放一个'替换'商业广告,它应该“覆盖”我们发送的商业音频。如果更换地点没有快速启动,听众会听到商业广告的开头我们是发送,然后当我们的数据被收到时,本地替换将开始,这听起来像是空中打嗝。)

为了确认我的脚本并不总是足够快地接收数据,我telnet到它正在监听的端口并观察在telnet窗口中收到的数据,然后查看Python输出(将输出的数据发送到stdout一接收到)我看到telnet输出和Python输出之间有1.5秒的延迟。这与我们在正常播出操作中观察到的延迟相同。

我之所以选择使用select()是因为我被要求多线程化脚本,我认为这是了解何时触发数据处理线程的好方法。我最初的想法是简单地循环尝试从我们正在监视的三个系统中的每个系统读取数据,并在找到数据时处理它。

我们的想法是,如果在另一个系统准备好读取数据时从一个系统处理数据,则可能会导致处理延迟并从该计算机发送数据。但是,我不能看到延迟与我现在所经历的那样重要。我正在考虑回到最初的计划。

只要及时收到数据,我宁愿坚持我所拥有的完美工作。有关为什么过长延迟的想法?

1 个答案:

答案 0 :(得分:0)

我认为这与您的timeout参数结合wlistxlist参数有关 考虑这段代码

write_list = []
exception_list = []
select.select([client_socket_1], write_list, exception_list)

它需要一个可选的超时参数,就像你使用它一样。文档说

  

select()还采用可选的第四个参数,即数字   如果没有频道,在断开监视之前等待的秒数   变得活跃。使用超时值可让主程序调用select()   作为更大的处理循环的一部分,在其间采取其他行动   检查网络输入。

由于空列表,可能会在返回之前始终等待一秒钟。尝试

ready_1 = select.select(
    [client_socket_1], 
    [client_socket_1], 
    [client_socket_1], 1
)    

或者您可以使用超时值0,

  

指定一个民意调查,永远不会阻止。