代码之家  ›  专栏  ›  技术社区  ›  Kevin

多处理超时?

  •  0
  • Kevin  · 技术社区  · 7 年前

    我已经搜索了StackOverflow,虽然我在这方面找到了很多问题,但我还没有找到适合我的情况的答案/不是一个强大的python程序员来调整他们的答案以满足我的需要。

    我在这里看了没用:

    kill a function after a certain time in windows

    Python: kill or terminate subprocess when timeout

    signal.alarm replacement in Windows [Python]

    我使用多处理一次运行多个SAP窗口来提取报告。已设置为按计划每5分钟运行一次。每隔一段时间,其中一个报告就会因为GUI界面而停止运行,而且永远不会停止。我没有收到错误或异常,它只是永远停止。我想要的是有一个超时功能,在SAP中执行这部分代码的过程中,如果时间超过4分钟,就会超时,关闭SAP,跳过其余代码,并等待下一个计划的报告时间。

    我正在使用Windows Python 2.7

    import multiprocessing
    from multiprocessing import Manager, Process
    import time
    import datetime
    
    ### OPEN SAP ###
    def start_SAP():
       print 'opening SAP program'
    
    ### REPORTS IN SAP ###
    def report_1(q, lock):
       while True:  # logic to get shared queue
           if not q.empty():
               lock.acquire()
               k = q.get()
               time.sleep(1)
               lock.release()
               break
           else:
               time.sleep(1)
       print 'running report 1'
    
    def report_2(q, lock):
       while True:  # logic to get shared queue
           if not q.empty():
               lock.acquire()
               k = q.get()
               time.sleep(1)
               lock.release()
               break
           else:
               time.sleep(1)
       print 'running report 2'
    
    def report_3(q, lock):
       while True:  # logic to get shared queue
           if not q.empty():
               lock.acquire()
               k = q.get()
               time.sleep(1)
               lock.release()
               break
           else:
               time.sleep(1)
    
       time.sleep(60000) #mimicking the stall for report 3 that takes longer than allotted time
       print 'running report 3'
    
    def report_N(q, lock):
       while True:  # logic to get shared queue
           if not q.empty():
               lock.acquire()
               k = q.get()
               time.sleep(1)
               lock.release()
               break
           else:
               time.sleep(1)
       print 'running report N'
    
    ### CLOSES SAP ###
    def close_SAP():
       print 'closes SAP'
    
    def format_file():
       print 'formatting files'
    
    def multi_daily_pull():
    
        lock = multiprocessing.Lock()  # creating a lock in multiprocessing
    
        shared_list = range(6)  # creating a shared list for all functions to use
        q = multiprocessing.Queue()  # creating an empty queue in mulitprocessing
        for n in shared_list:  # putting list into the queue
            q.put(n)
        print 'Starting process at ', time.strftime('%m/%d/%Y %H:%M:%S')
    
        print 'Starting SAP Pulls at ', time.strftime('%m/%d/%Y %H:%M:%S')
    
        StartSAP = Process(target=start_SAP)
        StartSAP.start()
        StartSAP.join()
    
        report1= Process(target=report_1, args=(q, lock))
        report2= Process(target=report_2, args=(q, lock))
        report3= Process(target=report_3, args=(q, lock))
        reportN= Process(target=report_N, args=(q, lock))
    
        report1.start()
        report2.start()
        report3.start()
        reportN.start()
    
        report1.join()
        report2.join()
        report3.join()
        reportN.join()
    
        EndSAP = Process(target=close_SAP)
        EndSAP.start()
        EndSAP.join()
    
        formatfile = Process(target=format_file)
        formatfile .start()
        formatfile .join()
    
    if __name__ == '__main__':
        multi_daily_pull()
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   martineau    5 年前

    一种方法是使用可选的超时参数 Process.join() 方法接受。这将使它最多只能阻塞该时间长度的调用线程。

    我还设置了 daemon 属性,以便主线程能够终止,即使它启动的某个进程仍在“运行”(或已挂起)。

    最后一点,你不需要 multiprocessing.Lock 控制访问a multiprocessing.Queue ,因为他们自动处理这方面的事情,所以我删除了它。出于某些其他原因,您可能仍然希望有一个标准输出,例如控制对标准输出的访问,以便从各个进程打印到标准输出不会重叠,也不会弄乱输出到屏幕的内容。

    import multiprocessing
    from multiprocessing import Process
    import time
    import datetime
    
    def start_SAP():
        print 'opening SAP program'
    
    ### REPORTS IN SAP ###
    def report_1(q):
        while True:  # logic to get shared queue
            if q.empty():
                time.sleep(1)
            else:
                k = q.get()
                time.sleep(1)
                break
    
        print 'report 1 finished'
    
    def report_2(q):
        while True:  # logic to get shared queue
            if q.empty():
                time.sleep(1)
            else:
                k = q.get()
                time.sleep(1)
                break
    
        print 'report 2 finished'
    
    def report_3(q):
        while True:  # logic to get shared queue
            if q.empty():
                time.sleep(1)
            else:
                k = q.get()
                time.sleep(60000) # Take longer than allotted time
                break
    
        print 'report 3 finished'
    
    
    def report_N(q):
        while True:  # logic to get shared queue
            if q.empty():
                time.sleep(1)
            else:
                k = q.get()
                time.sleep(1)
                break
    
        print 'report N finished'
    
    def close_SAP():
        print 'closing SAP'
    
    def format_file():
        print 'formatting files'
    
    def multi_daily_pull():
        shared_list = range(6)  # creating a shared list for all functions to use
        q = multiprocessing.Queue()  # creating an empty queue in mulitprocessing
        for n in shared_list:  # putting list into the queue
            q.put(n)
        print 'Starting process at ', time.strftime('%m/%d/%Y %H:%M:%S')
    
        print 'Starting SAP Pulls at ', time.strftime('%m/%d/%Y %H:%M:%S')
    
        StartSAP = Process(target=start_SAP)
        StartSAP.start()
        StartSAP.join()
    
        report1 = Process(target=report_1, args=(q,))
        report1.daemon = True
        report2 = Process(target=report_2, args=(q,))
        report2.daemon = True
        report3 = Process(target=report_3, args=(q,))
        report3.daemon = True
        reportN = Process(target=report_N, args=(q,))
        reportN.daemon = True
    
        report1.start()
        report2.start()
        report3.start()
        reportN.start()
    
        report1.join(30)
        report2.join(30)
        report3.join(30)
        reportN.join(30)
    
        EndSAP = Process(target=close_SAP)
        EndSAP.start()
        EndSAP.join()
    
        formatfile = Process(target=format_file)
        formatfile .start()
        formatfile .join()
    
    if __name__ == '__main__':
        multi_daily_pull()