如何通过 Python 使用定时器线程

How to use Timer Thread with Python

我正在编写一个 Ryu 应用程序(Python),其中有 if else 语句。如果条件 第一次满足,那么它应该启动定时器直到10秒,在在这 10 秒内,还会有其他数据包到达并匹配相同的条件 ,但我不想在每次满足条件时(在这 10 秒内)都启动计时器。总之,定时器应该运行并行

这是我用于线程的代码片段。 每次我 运行 这并发送多个数据包然后多个线程启动,而我只希望一个线程 运行 直到 10 秒

def timeit():
         time.sleep(10)
         aggr()
         return

def aggr():
         self.no_of_data=len(self.iot_data)
         self.ip_proto=proto
         self.ip_saddr=source
         self.ip_daddr=destination
         ip_head= pack('!BBHHHBBH16s16s' , self.ip_ihl_ver, self.ip_tos, self.ip_tot_len, self.ip_id, self.ip_frag_off, self.ip_ttl,self.ip_check,self.ip_proto, self.ip_saddr, self.ip_daddr)
         total_pkts= pack('!I', self.no_of_data)
         print "TOTALLLL,,,,",self.no_of_data
         ip_head="{" + ip_head + "}"
         total_pkts="{" + total_pkts + "}"
         s='$'
         data = s.join(self.iot_data)
         data="$" + data
         pckt= ip_head + total_pkts + data
         self.iot_data = []
         print "BUFFER: ", self.iot_data
         self.iot_data_size = 0
         self.start_time = time.time()
         self.logger.info("packet-out %s" % (repr(pckt),))
         out_port = ofproto.OFPP_FLOOD
         actions = [parser.OFPActionOutput(out_port)]
         out = parser.OFPPacketOut(datapath=datapath,
               buffer_id=ofproto.OFP_NO_BUFFER,
               in_port=in_port, actions=actions,                                          
               data=pckt)
         print "out--->" , out
         datapath.send_msg(out)
thread1 = threading.Thread(target=timeit)
thread1.start()
if  proto  == 150 and total_len  < 1500:
        if not thread1.isAlive():
                thread1.run()
        print "ifff"
        data = msg.data
        #print " # stores the packet data"
        self.iot_data.append(data)
        #print "# increment size counter"
        self.iot_data_size += total_len
        #elapsed_time = time.time() - self.start_time
        print "ELAPSED: ", elapsed_time
        print "BUFFER: ", self.iot_data

10 秒后,计时器应在第一个数据包到达时再次启动,并且应 运行 与相同的代码并行。 我对此很困惑。请任何人帮助。

我希望这是清楚的,如果不是很抱歉,请要求澄清。

谢谢

确实,您必须使用多线程(没有它可能会实现,但肯定会很痛苦)。这个想法是 运行 一个线程,它将 运行 一个休眠 10 秒和 returns 的函数。在这个函数 returns 之后,线程将被设置为不活动,直到我们 运行 下一次它。

通过了解我们可以写出下面的代码。所有细节和解释都写成注释,以便于参考。

import time
import threading

packet_groups = [] # Groups of packets inside 10 seconds.
group = [] # Temporary group that will get stored into packet_groups.

# The function that will count 10 seconds:
def timeit():
    sleep(10)
    return

# Do something with packets.
def packet_handler():
    ...

# Put all your code inside another function that does not create
# new thread each time. Create a thread in main and then run this function.
def get_packets(thread1):
    ... # get packets
    if dst == 'some_address':
        # Check if thread is alive. If it is alive, a counter is running.
        # If it is not alive, then we must start the counter by running
        # thread.
        if not thread1.isAlive():
            thread1.run()
            packet_handler(packet, True)
        else:
            packet_handler(packet, False)

if __name__ == '__main__':
    # Create thread.
    thread1 = threading.Thread(target=timeit)
    # Start the thread. This is done only once per each thread.
    thread1.start()

    get_packets(thread1)

现在既然你提到你想在这 10 秒的块内对数据包进行分组,你可以这样实现 packet_handler()

def packet_handler(packet, new):
    # If we started new thread and the group isn't empty, we must
    # append group to packet_groups (that is all groups) and reset
    # the group to only contain current packet
    if new and group != []:
        packet_groups.append(group)
        group = [packet]
        return
    # If group isn't new, we are still inside 10 seconds block. We
    # just append the current packet to this block.
    if not new:
        group.append(packet)

如果您希望能够打印或以任何其他方式能够显示计时器,则您不能睡 10 秒,因为如果您睡 10 秒,其间什么也做不了。在这种情况下,您想将 timeit() 更改为如下内容:

def timeit():
    for i in range(10):
        print 'Time remaining: {0}s'.format(10-i)
        sleep(1)
    return