从范围外的多处理管理器传递结果列表

Passing result-list from Multiprocessing Manager outside scope

我正在尝试扫描域以进行渗透测试,该程序使用 Multiprocessing,结果列表是从 Processes 传递过来的;回到主要功能。

我曾尝试在 global 中也使用 class 中提到的全局变量。使用它让我想起进程存在于不同的内存中。所以我改用 manager.list() ;在进程之间共享内存

这是我试过的方法:

from multiprocessing import Process, cpu_count, Manager

class variably:
    variably=bla..
    .... 

def engine(domainlist, R):
    for domain in domainlist:
        try:
            r = requests.get("http://" + domain, headers=headers, timeout=0.7, allow_redirects=False)
            if r.status_code == expected_response:
                print("Success" + domain)
                print(domain, file=open("LazyWritesForDebugPurposes.txt", "a"))
                R.append(str(domain))
            elif r.status_code != expected_response:
                print("Failed" + domain + str(r.status_code))

        except:
            pass

def fromtext():
    ....
    R = []
    with Manager() as manager:
        num_cpus = cpu_count()
        processes = []
        R = manager.list()
        for process_num in range(num_cpus):
            section = domainlist[process_num::num_cpus]
            p = Process(target=engine, args=(section,R,))
            p.start()
            processes.append(p)
        for p in processes:
            p.join()
        print(R)
    print(R)

    print("")
    print(" Total of Domains Queried : "  + colors.RED_BG + " "+str(len(R)) +" "+ colors.ENDC)
    if len(inf.result_success) >= 0:
        print(" Successfull Result : " + colors.GREEN_BG + " "+str(len(R))+ " "+colors.ENDC)
fromtext()

对于任何无效的语法或缩进,我们深表歉意,试图将代码简化为更短的代码段。

以上代码 returns BrokenPipe 有时会出现 ConnectionRefused 错误。 从异常中,我可以看到列表已经附加为:['Domain.com','Domain_2.com'] 但不知何故引发了异常。

这里有一些关于这个问题的截图: Problematic Screenshot

编辑:

看起来列表只能在 manager() 范围内传递,我如何扩展在范围外传递的数据,例如在不同的函数中调用列表。以下代码有效:

    with Manager() as manager:
        num_cpus = cpu_count()
        processes = []
        R = manager.list()
        for process_num in range(num_cpus):
            section = domainlist[process_num::num_cpus]
            p = Process(target=engine, args=(section,R,))
            p.start()
            processes.append(p)
        for p in processes:
            p.join()

        str(len(R))

您确实想使用队列。在主线程中创建一个 multiprocessing.SimpleQueue 并将其传递给所有子进程。他们可以将项目添加到此队列。

创建自己的经理几乎总是错误的。

问题是我必须通过设置新变量将 manager.list() 显式转换为另一个普通列表,并使用 global 使其在另一个函数中可用。我知道它很脏,还没有尝试使用 Queue() 但现在,至少它在工作。

def executor():
    global R
    .... 
    with Manager() as manager:
        num_cpus = cpu_count()
        processes = []
        R = manager.list()
        for process_num in range(num_cpus):
            section = domainlist[process_num::num_cpus]
            p = Process(target=engine, args=(section,R,))
            p.start()
            processes.append(p)
        for p in processes:
            p.join()

        R = list(R)

    print(R)

如果能对此进行简化,我将不胜感激。