簡體   English   中英

如何將異常從一個進程傳遞到另一個進程?

[英]How to pass exception from one process to another?

如果停止功能的運行狀態為“停止”,我想在上傳功能中引發異常。 這似乎不起作用。 我正在使用Pipe傳遞異常。 怎么了?

def upload(instances, u1):
    for instance in instance:
        try:
            u1.recv()
            #do_something
        except:
            #do_something_else
            continue         

def stop(instances, s1):
    for instance in instances:
        RunningStatus = instance[4]
        if RunningStatus.lower() == 'stopped'.lower():
            s1.send(Exception) # I want to raise exception in upload function 
                               # from here

if __name__ == '__main__':
    s1, u1 = multiprocessing.Pipe()
    s = multiprocessing.Process(target = stop, args = (instances, s1,))
    u = multiprocessing.Process(target = upload, args = (instances, u1))
    s.start()
    u.start()
    u.join()

這是如何將Exception對象從一個進程發送到另一個進程的示例。 我還嘗試發送完整的異常信息(由sys.exc_info返回),但是,這樣做足夠合理。 可以始終將回溯信息格式化為字符串並將其發送(參見回溯模塊)。

已在Ubuntu 14.04 Python 2.7、3.4(Ubuntu提供)和3.5(Continuum)上進行了測試。

from __future__ import print_function

import sys
import multiprocessing
import time

def upload(u1):
    i=0
    try:
        while True:
            print('>upload>',i)
            i+=1
            if u1.poll():
                # tvt = u1.recv()
                # raise tvt[0], tvt[1], tvt[2] # Python 2.7
                e = u1.recv()
                raise e
            time.sleep(0.1)
    except Exception as e:
        print('Exception caught:',e)
        print('exiting')

def stop(s1):
    try:
        while True:
            for j in range(100,110):
                time.sleep(0.1)
                if 105==j:
                    raise RuntimeError("oh dear at j={}".format(j))
    except Exception as e:
        # tvt = sys.exc_info()
        # s1.send(tvt) # doesn't work; tracebacks are not pickle'able
        s1.send(e)

if __name__ == '__main__':
    s1, u1 = multiprocessing.Pipe()
    s = multiprocessing.Process(target = stop, args = (s1,))
    u = multiprocessing.Process(target = upload, args = (u1,))
    s.start()
    u.start()
    u.join()

輸出:

>upload> 0
>upload> 1
>upload> 2
>upload> 3
>upload> 4
>upload> 5
>upload> 6
Exception caught: oh dear at j=105
exiting

您可能想研究使用事件對象而不是管道和異常組合。 通過使用事件原語在您的進程之間共享數據,您可以讓Upload函數監視事件並在stop函數發現問題時觸發您的邏輯。

根據您的示例,我假設實例中的每個實例對象都是一個數組,因此,通過使用附加元素擴展該數組,您可以為每個實例具有唯一事件。

def upload(instances, u1):
    for instance in instance:
        if instance[5].is_set(): # events only return TRUE if they are set
            #Exception logic would go here

    else: 
        u1.recv()
        #do_something


def stop(instances, s1):
    for instance in instances:
        RunningStatus = instance[4]
        if RunningStatus.lower() == 'stopped'.lower():
            instance[5].set() # Set the event to TRUE 

if __name__ == '__main__':
    for instance in instances:
        instance[5] = multiprocessing.Event() # create a new event semaphore 
    s = multiprocessing.Process(target = stop, args = (instances, s1,))
    u = multiprocessing.Process(target = upload, args = (instances, u1))
    s.start()
    u.start()
    u.join()

可以在以下位置找到多處理原語的完整列表: https : //docs.python.org/2/library/multiprocessing.html#synchronization-primitives

這是其他多處理對象對原語的各種用法的一些很好的示例: https : //pymotw.com/2/multiprocessing/communication.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM