import gc
import multiprocessing

class Cycle(object):
	def __init__(self):
		self.g = self.gen()
		next(self.g)
	def gen(self):
		try:
			yield self
		finally:
			print('Doing one-time cleanup')

def work():
	# Pretend this does work that triggers a collection cycle
	gc.collect()

# Get some allocations done now that would have triggered an
# inconvenient collection if we did them later
p = multiprocessing.Process(target=work)
p.start()
p.join()

print('Creating cyclic trash')
Cycle()

try:
	p = multiprocessing.Process(target=work)
	p.start()
	p.join()

	work()

	print('Oops, did cleanup twice')
finally:
	print('Doing other one-time cleanup')

print("*Didn't* do the other cleanup twice, even though we forked to run p")