# Python modules import time import mmap import os import sys PY_MAJOR_VERSION = sys.version_info[0] # hashlib is only available in Python >= 2.5. I still want to support # older Pythons so I import md5 if hashlib is not available. Fortunately # md5 can masquerade as hashlib for my purposes. try: import hashlib except ImportError: import md5 as hashlib # 3rd party modules import posix_ipc # Utils for this demo import utils PY_MAJOR_VERSION = sys.version_info[0] utils.say("Oooo 'ello, I'm Mrs. Conclusion!") params = utils.read_params() # Mrs. Premise has already created the semaphore and shared memory. # I just need to get handles to them. memory = posix_ipc.SharedMemory(params["SHARED_MEMORY_NAME"]) semaphore = posix_ipc.Semaphore(params["SEMAPHORE_NAME"]) # MMap the shared memory mapfile = mmap.mmap(memory.fd, memory.size) # Once I've mmapped the file descriptor, I can close it without # interfering with the mmap. This also demonstrates that os.close() is a # perfectly legitimate alternative to the SharedMemory's close_fd() method. os.close(memory.fd) what_i_wrote = "" for i in range(0, params["ITERATIONS"]): utils.say("iteration %d" % i) if not params["LIVE_DANGEROUSLY"]: # Wait for Mrs. Premise to free up the semaphore. utils.say("Waiting to acquire the semaphore") semaphore.acquire() s = utils.read_from_memory(mapfile) while s == what_i_wrote: if not params["LIVE_DANGEROUSLY"]: # Release the semaphore... utils.say("Releasing the semaphore") semaphore.release() # ...and wait for it to become available again. utils.say("Waiting to acquire the semaphore") semaphore.acquire() s = utils.read_from_memory(mapfile) if what_i_wrote: if PY_MAJOR_VERSION > 2: what_i_wrote = what_i_wrote.encode() try: assert(s == hashlib.md5(what_i_wrote).hexdigest()) except AssertionError: utils.raise_error(AssertionError, "Shared memory corruption after %d iterations." % i) if PY_MAJOR_VERSION > 2: s = s.encode() what_i_wrote = hashlib.md5(s).hexdigest() utils.write_to_memory(mapfile, what_i_wrote) if not params["LIVE_DANGEROUSLY"]: utils.say("Releasing the semaphore") semaphore.release() semaphore.close() mapfile.close() utils.say("") utils.say("%d iterations complete" % (i + 1))