fixed threading/multiprocessing
This commit is contained in:
@@ -5,6 +5,7 @@ import multiprocessing
|
|||||||
import threading
|
import threading
|
||||||
import concurrent.futures as concfut
|
import concurrent.futures as concfut
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
from . import batch
|
from . import batch
|
||||||
from . import plan
|
from . import plan
|
||||||
@@ -20,42 +21,76 @@ def load(exp_file):
|
|||||||
with open(exp_file) as efile:
|
with open(exp_file) as efile:
|
||||||
exp_obj = json.loads(efile.read())
|
exp_obj = json.loads(efile.read())
|
||||||
exp_obj["load"] = pl.Path(exp_obj["load"])
|
exp_obj["load"] = pl.Path(exp_obj["load"])
|
||||||
|
|
||||||
exp_mod = impmach.SourceFileLoader(exp_obj["load"].stem,
|
exp_mod = impmach.SourceFileLoader(exp_obj["load"].stem,
|
||||||
str(exp_obj["load"])).load_module()
|
str(exp_obj["load"])).load_module()
|
||||||
|
|
||||||
return Dispatcher(exp_mod.run, exp_plan, os.cpu_count())
|
num_workers = 1
|
||||||
|
|
||||||
|
if "workers" in exp_obj:
|
||||||
|
if exp_obj["workers"] == "all":
|
||||||
|
num_workers = os.cpu_count()
|
||||||
|
else:
|
||||||
|
num_workers = int(exp_obj["workers"])
|
||||||
|
|
||||||
|
return Dispatcher(exp_mod, exp_plan, num_workers)
|
||||||
|
|
||||||
class Dispatcher (threading.Thread):
|
class Dispatcher (threading.Thread):
|
||||||
def __init__(self, exp_func, exp_plan, num_workers):
|
def __init__(self, exp_mod, exp_plan, num_workers):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
self.__exp_func = exp_func
|
|
||||||
self.__plan = exp_plan
|
|
||||||
|
|
||||||
self.__num_workers = num_workers
|
self.__num_workers = num_workers
|
||||||
self.__workers = []
|
self.__workers = []
|
||||||
|
self.__stop_called = threading.Event()
|
||||||
|
|
||||||
for i in range(self.__num_workers):
|
for i in range(self.__num_workers):
|
||||||
self.__workers.append(multiprocessing.Process(target=self.__run_exp,
|
self.__workers.append(Worker(exp_mod, exp_plan))
|
||||||
args=(self.__exp_func,
|
|
||||||
self.__plan)))
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for worker in self.__workers:
|
for worker in self.__workers:
|
||||||
worker.start()
|
worker.start()
|
||||||
|
|
||||||
for worker in self.__workers:
|
def wait_to_continue(workers, stop_called):
|
||||||
|
any_worker_alive = any(map(lambda w: w.is_alive(), workers))
|
||||||
|
|
||||||
|
while any_worker_alive and not stop_called.is_set():
|
||||||
|
time.sleep(0)
|
||||||
|
|
||||||
|
waiter = threading.Thread(target=wait_to_continue,
|
||||||
|
args=(self.__workers,
|
||||||
|
self.__stop_called))
|
||||||
|
|
||||||
|
waiter.start()
|
||||||
|
waiter.join()
|
||||||
|
|
||||||
|
if self.__stop_called.is_set():
|
||||||
|
for worker in self.__workers:
|
||||||
|
worker.terminate()
|
||||||
|
|
||||||
|
for worker in self.__workers:
|
||||||
worker.join()
|
worker.join()
|
||||||
|
|
||||||
@staticmethod
|
def stop(self):
|
||||||
def __run_exp(exp_func, exp_plan):
|
self.__stop_called.set()
|
||||||
instance = exp_plan.next()
|
|
||||||
|
|
||||||
while instance != None:
|
class Worker (multiprocessing.Process):
|
||||||
exp_func(instance)
|
def __init__(self, exp_mod, exp_plan):
|
||||||
|
multiprocessing.Process.__init__(self)
|
||||||
|
|
||||||
|
self.__exp_mod = exp_mod
|
||||||
|
self.__exp_plan = exp_plan
|
||||||
|
|
||||||
exp_plan.done_with(instance)
|
def run(self):
|
||||||
|
instance = self.__exp_plan.next()
|
||||||
|
|
||||||
|
while instance != None:
|
||||||
|
self.__exp_mod.run(instance)
|
||||||
|
self.__exp_plan.done_with(instance)
|
||||||
|
|
||||||
|
instance = self.__exp_plan.next()
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.__exp_plan.delete()
|
||||||
|
multiprocessing.Process.terminate(self)
|
||||||
|
|
||||||
instance = exp_plan.next()
|
|
||||||
|
|
||||||
|
@@ -104,8 +104,8 @@ class Plan:
|
|||||||
elif self.file.is_file():
|
elif self.file.is_file():
|
||||||
self.file.unlink()
|
self.file.unlink()
|
||||||
|
|
||||||
def __del__(self):
|
#def __del__(self):
|
||||||
|
def delete(self):
|
||||||
with self.__lock:
|
with self.__lock:
|
||||||
self.__load()
|
self.__load()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user