-1

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

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

谢谢

4

1 回答 1

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
于 2017-09-04T08:04:04.133 回答