如何在Python中使用Timer Thread

时间:2017-09-04 07:53:28

标签: python multithreading ryu

我正在编写一个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秒后,再次计时器应该在第一个数据包到达时启动,它应该与相同的代码并行运行。 我对此非常困惑。请任何人帮忙。

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

谢谢

1 个答案:

答案 0 :(得分:0)

实际上,你必须采用多线程(没有它可能会实现,但它肯定会是一个痛苦的屁股)。我们的想法是运行一个线程,该线程将运行一个休眠10秒并返回的函数。返回此函数后,该线程将被设置为非活动状态,直到我们下次运行它为止。

知道我们可以编写以下代码。所有细节和说明都写成注释,以便于参考。

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