简体   繁体   English

在共享对象扭曲的情况下分叉多个过程

[英]Forking multiple process in twisted with shared object

I want to fork multiple processes with twisted. 我想分叉多个进程。 I know from the discussion here that Twisted and multiprocessing are not compatible with each other. 这里的讨论中,我知道Twisted和多重处理彼此不兼容。 Its true that I can launch separate processes from different terminals to achieve the same effect, but I cannot do so. 的确,我可以从不同的终端启动单独的进程来达到相同的效果,但是我不能这样做。

There is a big object (size in GBs) which I want to share among different python processes (cannot load the same object multiple times on RAM, due to RAM limitation on my computer) 我想在不同的python进程之间共享一个大对象(以GB为单位)(由于计算机上的RAM限制,无法多次在RAM上加载同一对象)

What I am trying to do is 我想做的是

  1. Start multiple rabbit-mq consumers asynchronously in a single process. 在单个进程中异步启动多个Rabbit-mq使用者。
  2. Fork multiple such processes with a common shared object to leverage all CPUs in my system. 用公共共享对象分叉多个此类进程,以利用系统中的所有CPU。

I am able to achieve step one. 我能够实现第一步。 Here is what I come up with - 这是我想出的-

import pika

class PikaFactory(protocol.ReconnectingClientFactory):
    def __init__(self, parameters, task_number=0, shared_obj=None):
        self.parameters = parameters
        self.task_count = total_tasks
        self.task_number = task_number
        self.shared_obj= shared_obj

    def buildProtocol(self, addr):
        self.resetDelay()
        logger.info('Task: %s, Connected' % self.task_number)
        proto = twisted_connection.TwistedProtocolConnection(self.parameters)
        # run is a async function that consumes the rabbit-queue
        proto.ready.addCallback(run, self.task_number, self.shared_obj)
        return proto

    # Rest of the implementation ...........

def run_tasks(shared_obj):
    from twisted.internet import reactor
    try:
        parameters = pika.ConnectionParameters(**CONNECTION_PARAMETERS)
        factory = PikaFactory(parameters, 0, shared_obj)

        for i in range(total_tasks):
            # Launch multiple async-tasks in the same process
            reactor.connectTCP(parameters.host, parameters.port, factory)

        logger.info(' [*] Waiting for messages. To exit press CTRL+C')
        reactor.run()
    except:
        logger.exception("Error")
        reactor.stop()

if __name__ == '__main__':
    obj = Fibonacci()
    run_tasks(obj)

Now to fork multiple processes I have written this code. 现在分叉多个进程,我已经编写了这段代码。

from multiprocessing.managers import BaseManager
class MyManager(BaseManager):
    """
    This Manager is responsible for coordinating shared
    information state between all processes
    """
    pass

# Register your custom "Fibonacci" class with the manager
# This is the class I want to share among multiple processes
MyManager.register('Fibonacci', Fibonacci)

def Manager():
    m = MyManager()
    m.start()
    return m

def run_multiple_processes():
    manager = Manager()
    # object I want to share among multiple processes 
    fibonacci = manager.Fibonacci()
    pool = multiprocessing.Pool(processes=workers)
    for i in range(0, workers):
        pool.apply_async(run_tasks, (fibonacci, ))

    # Stay alive
    try:
        while True:
            continue
    except KeyboardInterrupt:
        logger.error(' [*] Exiting...')
        pool.terminate()
        pool.join()

I am getting some random errors while running the above code like - 我在运行上述代码时遇到一些随机错误,例如-

builtins.AttributeError: '_SIGCHLDWaker' object has no attribute 'doWrite'

What would be the twisted way to launch multiple process and share a custom object between them. 启动多个进程并在它们之间共享自定义对象的扭曲方式是什么。 No writes will be performed on the object, the object is used to only read from its attributes. 将不会对该对象执行任何写操作,该对象仅用于从其属性读取。

Thanks in advance. 提前致谢。

While searching I encountered this post - twisted incompatible with python multiprocessing . 在搜索时,我遇到了这种与python多处理不兼容的扭曲现象 The answer exists in this post only quoting his words - 在这篇文章中,答案仅是引用他的话-

"not loading any of Twisted until you've already created the child processes. This means not even importing Twisted until after you've created the child processes." “在创建子进程之前,不要加载任何Twisted。这意味着直到创建子进程后,才导入Twisted。”

Thanks @Jean-Paul Calderone for this useful comment. 感谢@ Jean-Paul Calderone的有用评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM