Python asynchronous processing in existing loop

2019-07-30 18:36发布

问题:

I'm creating a module for OpenERP in which I have to launch an ongoing process.

OpenERP runs in a continuous loop. My process has to be launched when I click on a button, and it has to keep running without holding up OpenERP's execution.

To simplify it, I have this code:

#!/usr/bin/python
import multiprocessing
import time

def f(name):
    while True:
        try:
            print 'hello', name
            time.sleep(1)
        except KeyboardInterrupt:
            return

if __name__ == "__main__":
    count = 0
    while True:
        count += 1
        print "Pass %d" % count
        pool = multiprocessing.Pool(1)
        result = pool.apply_async(f, args=['bob'])
        try:
            result.get()
        except KeyboardInterrupt:
            #pass
            print 'Interrupted'
        time.sleep(1)

When executed, Pass 1 is printed once and then an endless series of hello bob is printed until CTRL+C is pressed. Then Pass 2 is obtained and so on, as shown below:

Pass 1
hello bob
hello bob
hello bob
^CInterrupted
Pass 2
hello bob
hello bob
hello bob
hello bob

I would like the passes to keep increasing in parallel with the hello bob's.

How do I do that?

回答1:

Here what you can do id you can create then Multi Threaded Implementation of Python under the server memory, which will run independently then server execution thread. Trick behind this will be used is we will fork one thread from server on your required click and we will assign all server variable separate copy to the new Thread so that thread will execute independently and at then end of process you have to commit the transaction as this process will be not main server process. Here the small example of it how you can do it .

import pprint
import pooler
from threading import Thread
import datetime
import logging
pp = pprint.PrettyPrinter(indent=4)

class myThread(Thread):
    """
    """
    def __init__(self, obj, cr, uid, context=None):
        Thread.__init__(self)
        self.external_id_field = 'id'
        self.obj = obj
        self.cr = cr
        self.uid = uid
        self.context = context or {}
        self.logger = logging.getLogger(module_name)
        self.initialize()

    """
        Abstract Method to be implemented in the real instance
    """
    def initialize(self):
        """
            init before import
            usually for the login
        """
        pass

    def init_run(self):
        """
            call after intialize run in the thread, not in the main process
            TO use for long initialization operation
        """
        pass

    def run(self):
        """
            this is the Entry point to launch the process(Thread)
        """
        try:
            self.init_run()
            #Your Code Goes Here
            #TODO Add Business Logic
            self.cr.commit()
        except Exception, err:
            sh = StringIO.StringIO()
            traceback.print_exc(file=sh)
            error = sh.getvalue()
            print error
        self.cr.close()

LIke this you can add some code in some module like (import_base module in 6.1 or trunk) Now what Next you can do is you can make extended implementation of this and then make instace of the service or you can directly start forking the treads like following code:

    service = myServcie(self, cr, uid, context)
    service.start()

now this we start background services which run faster and give you freedom to use the UI.

Hope this will help you Thank You