Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I would approach your needs using threads and locks.</p> <p>In fact, I love an open sourced ThreadPool written by Pepe, a friend of mine.</p> <p>Here is ThreadPool code, and after that, a possible solution:</p> <pre><code>#! /usr/bin/python # -*- coding: utf-8 -*- # File: threadPool.py import threading import Queue import time import sys import traceback import datetime Instance = None def getInstance(): global Instance if not Instance: Instance = ThreadPool() return Instance class ThreadPool: def __init__(self,maxWorkers = 10): self.tasks = Queue.Queue() self.workers = 0 self.working = 0 self.maxWorkers = maxWorkers self.allKilled = threading.Event() self.countLock = threading.RLock() self.timers = {} self.timersLock = threading.Lock() self.timersThreadLock = threading.Lock() self.timersEvent = threading.Event() self.allKilled.set() def run(self,target,callback = None, *args, **kargs): """ starts task. target = callable to run with *args and **kargs arguments. callback = callable executed when target ends callback sould accept one parameter where target's return value is passed. If callback is None it's ignored. """ self.countLock.acquire() if not self.workers: self.addWorker() self.countLock.release() self.tasks.put((target,callback,args,kargs)) def setMaxWorkers(self,num): """ Sets the maximum workers to create. num = max workers If number passed is lower than active workers it will kill workers to match that number. """ self.countLock.acquire() self.maxWorkers = num if self.workers &gt; self.maxWorkers: self.killWorker(self.workers - self.maxWorkers) self.countLock.release() def addWorker(self,num = 1): """ Add workers. num = number of workers to create/add. """ for x in xrange(num): self.countLock.acquire() self.workers += 1 self.allKilled.clear() self.countLock.release() t = threading.Thread(target = self.__workerThread) t.setDaemon(True) t.start() def killWorker(self,num = 1): """ Kill workers. num = number of workers to kill. """ self.countLock.acquire() if num &gt; self.workers: num = self.workers self.countLock.release() for x in xrange(num): self.tasks.put("exit") def killAllWorkers(self,wait = None): """ Kill all active workers. wait = seconds to wait until last worker ends if None it waits forever. """ self.countLock.acquire() self.killWorker(self.workers) self.countLock.release() self.allKilled.wait(wait) def __workerThread(self): while True: task = self.tasks.get() # exit is "special" tasks to kill thread if task == "exit": break self.countLock.acquire() self.working += 1 if (self.working &gt;= self.workers) and (self.workers &lt; self.maxWorkers): # create thread on demand self.addWorker() self.countLock.release() fun,cb,args,kargs = task try: ret = fun(*args,**kargs) if cb: cb(ret) except: ty,val,tb = sys.exc_info() print "Thread Catch:%s" % "".join(traceback.format_exception(ty,val,tb)) self.countLock.acquire() self.working -= 1 self.countLock.release() del(fun) # Dereference all del(cb) del(args) del(kargs) del(task) self.countLock.acquire() self.workers -= 1 if not self.workers: self.allKilled.set() self.countLock.release() def timer(self, cb, period): """ Add or remove timers. cb = callback function. period = period in seconds (float) if period is 0 timer is deleted. """ self.run(self.__timerThread, None, cb, period) def __timerThread(self, cb, period): self.timersLock.acquire() self.timersEvent.set() if not period: if cb in self.timers: del(self.timers[cb]) self.timersLock.release() return self.timers[cb] = [period,time.time()] self.timersLock.release() if not self.timersThreadLock.acquire(0): return while True: self.timersLock.acquire() if len(self.timers) == 0: self.timersThreadLock.release() self.timersLock.release() break minWait = 30*24*3600 now = time.time() for k,v in self.timers.items(): period, last = v wait = period - (now - last) if wait &lt;=0: self.run(k) wait = period v[1] = now if wait &lt; minWait: minWait = wait self.timersLock.release() self.timersEvent.wait(minWait) self.timersEvent.clear() </code></pre> <p>And a possible solution:</p> <pre><code>#! /usr/bin/python # -*- coding: utf-8 -*- # File: a.py import threadPool import time import threading class A: def __init__(self): self.a = 1 self.alock = threading.Lock() self.tp = threadPool.getInstance() def bar(self): self.alock.acquire() self.a = 1 self.alock.release() def foo(self): self.tp.timer(self.bar, 2) while True: self.alock.acquire() self.a = self.a * 12 self.alock.release() print "A : ",self.a time.sleep(0.1) a = A() a.foo() </code></pre> <p>Run:</p> <pre><code>$ python a.py </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload