Reputation: 6780
I have a code that spins off new multiprocessing Process
-es, giving them a serialized name using itertools.count
to auto-increment the serial.
This is a glimpse of the code:
class WorkerStation(object):
def __init__(self, basename, factory):
# factory is a subclass of multiprocessing.Process
self.basename = basename
self.factory = factory
self.serie = itertools.count(start=1)
self.workers = []
def launch_workers(want_count):
while _count_active() < want_count:
name = '{0}-{1}'.format(self.basename, self.serie.next())
new_worker = self.factory(name=name)
new_worker.start()
print('Launched ', name)
self.workers.append(new_worker)
def _count_active():
# It is possible as we spun off new workers, some earlier workers
# have terminated. The is_alive() also join() these deceased
# workers.
self.workers = [w for w in self.workers if w.is_alive()]
return len(self.workers)
Now if I instantiate the WorkerStation
for the first time, e.g.:
station_1 = WorkerStation(basename="st1", factory=WorkerClassOne)
station_1.launch_workers(want_count=5)
I can see the serie
to be increasing properly, i.e., I'll see Launched st1-1
up to Launched st1-5
But interestingly, the second time I instantiate this class:
station_2 = WorkerStation(basename="st2", factory=WorkerClassTwo)
station_2.launch_workers(want_count=2)
I'll see serie
no longer incrementing, i.e., I'll see TWO lines of Launched st2-1
.
How is this possible? How could itertools.count
work for the first instantiaton, but no longer work for the second?
Upvotes: 1
Views: 306
Reputation: 6780
Okay folks, it's apparently a mistake in the code.
I'll paste here (part of) two methods whose interaction caused this grief:
def maintain_flights(self, target=None, force=False):
# If target not specified, invoke the auto_count() method to automatically
# determine the number of workers needed.
target = target or self.auto_count()
... lots of code removed ...
def rewind(self):
self.maintain_flights(target=0, force=True)
self.serie = itertools.count(start=1)
The main part of the program, during certain stages, will invoke the .rewind()
method to reduce the number of workers to 0.
As you can see, invoking the method with target=0
will cause the left side of the target or self.auto_count()
expression to be false, resulting the code to invoke the self.auto_count()
method.
So, instead of ending with zero workers, I got 1 worker.
Afterwards, the self.serie
object got 'reset' to start counting at 1.
A bit later in the main code, the main code asks for 2 workers. It already got 1 worker from the botched rewind()
attempt, and it added the second worker with serie
again starting from 1.
I've replaced the offending code with this line:
target = target if target is not None else self.auto_count()
And now it works splendidly!
Thanks for the assistance, and apologies if I've sent you all on a wild goose-chase.
Upvotes: 1