当一个失败时,如何停止Python中所有正在运行的线程?

时间:2018-06-07 23:39:19

标签: python multithreading multiprocessing scapy arp

我目前正在开发一个旨在对ARP服务进行压力测试的Python 3脚本。目前,我正在创建高达255" worker"线程然后让它们发送最多2 ^ 15个数据包来对服务器进行压力测试。这是我运行的主要测试脚本:

if __name__ == '__main__':
    for i in range(0, 8):
        for j in range(0, 15):
            print("Multithreading test with", 2**i, "workers and ", 2**j,
                  "packets:")
            sleep(3)
            try:
                arp_load_test.__main__(2**i)
            except:
                print("Multithreading test failed at", 2**i, "workers and ",
                      2**j, "packets:")
                break

    print("Moving on to the multiprocessing test.")
    sleep(10)

    for i in range(0, 15):
        print("Multiprocessing test with", 2**i, "workers:")
        sleep(3)
        try:
            arp_load_test2.__main__(2**i)
        except:
            print("Multiprocessing test failed at", 2**i, "workers.")
            print("\n\n\t\t\t\tDONE!")
            break

第一个代码块测试多线程,第二个代码块执行相同的操作,但多处理除外。 arp_load_test.pyarp_load_test2.py多处理的多线程版本。在每个except循环的for部分中,我想在其中一个线程失败时立即结束循环。我怎么做?这是arp_load_test.py的代码,而arp_load_test2.py几乎完全相同:

def __main__(threaders = 10, items = 10):
    print("\tStarting threading main method\n")
    sleep(1)
    a = datetime.datetime.now()
    # create a logger object
    logging.basicConfig(filename = "arp_multithreading_log.txt",
                        format = "%(asctime)s %(message)s",
                        level = logging.INFO)

    # default values
    interface = "enp0s8"
    workers = threaders
    packets = items
    dstip = "192.168.30.1"
    # parse the command line
    try:
        opts, args = getopt.getopt(sys.argv[1:], "i:w:n:d:", ["interface=",
                                                              "workers=",
                                                              "packets=",
                                                              "dstip="])
    except getopt.GetoptError as err:
        print("Error: ", str(err), file = sys.stderr)
        sys.exit(-1)
    # override defaults with the options passed in on the command line
    for o, a in opts:
        if o in ("-i", "--interface"):
            interface = a
        elif o in ("-w", "--workers"):
            w = int(a)
            if w > 254:
                workers = 254
                print("Max worker threads is 254. Using 254 workers",
                      file = sys.stderr)
            elif w < 1:
                workers = 1
                print("Min worker threads is 1. Using 1 worker",
                      file = sys.stderr)
            else:
                workers = w
        elif o in ("-n", "--packets"):
            packets = int(a)
        elif o in ("-d", "--dstip"):
            dstip = a
        else:
            assert False, "unhandled option"
    # create an empty list as a thread pool
    office = []
    # give all the workers jobs in the office
    for i in range(workers):
        office.append(ArpTestThread(i, "ARP-" + str(i), i, interface, packets,
                                    dstip))

    # do all the work
    logging.info("BEGIN ARP FLOOD TEST")
    for worker in office:
        worker.daemon = True
        worker.start()
    for worker in office:
        worker.join()

    b = datetime.datetime.now()
    print("\tSent", len(office) * packets, "packets!\n")
    print("It took", a - b, "seconds!")
    logging.info("END ARP FLOOD TEST\n")
    sleep(5)
    ##### end __main__

ArpTestThreadthreading.Thread(或Process)的子对象,用于将数据包发送到ARP服务。此外,我通过终端从VM内部运行测试脚本,但我没有使用程序设置使用的任何命令行选项,我只是添加参数而不是b / c lazy。

我是否需要在类文件中放置try block而不是测试脚本?我已经完成了90%的类文件代码,并且正在更新它并尝试收集有关它的功能的数据,并优化它以正确地强调ARP服务。我希望测试脚本中的for循环(这篇文章的第一部分代码)中断,停止所有当前运行的线程,并在其中一个线程/之后打印出程序失败的时间点进程崩溃。这可能吗?

编辑: 建议的重复问题并不能解决我的问题。我正在尝试发送数据包,并且它不会引发异常,直到程序本质上耗尽内存以继续将数据包发送到ARP服务。在程序本身中断之前我没有异常,因此建议使用简单信号的可能解决方案不起作用。

该程序可以成功完成。线程/进程可以(并且应该)开始,发送数据包,然后关闭。如果在任何单个线程/进程中发生了某些事情,我希望当前运行的所有内容都停止,然后基本上将错误消息打印到控制台。

0 个答案:

没有答案