How can unrelated processes cooperate using a futex?
Let's say I have unrelated processes, one being, say, an apache subprocess with my module, another being e.g. a background script.
I'd like to establish a condition variable with a mutex between the two using a futex, to benefit for user-space fast code path.
It seems to me that memory at which mutex is stored could be in a mmap
'd file, if that memory is mapped, e.g. mlock
'd the two processes could theoretically issue futex calls against same address.
Alternatively, perhaps a futex can be passed from one process to another using FUTEX_FD
.
Code submissions low-, high-level and dynamic languages are accepted (C, C++, Python, etc.). "robust futex" API must be supported too.
References:
Thanks Phillip and Felix M. for pointers.
Python user code (file with data structures already exists, initialised with PTHREAD_PROCESS_SHARED
)
with open("/tmp/semaphore", "rb+") as f:
m = mmap.mmap(f.fileno(), 0) # default: all file, share, read-write
data = ffi.cast("unsigned long[3]", id(m))[2] # pointer to mapped area, 64-bit CPython
lock = ffi.cast("pthread_mutex_t *", data)
cond = ffi.cast("pthread_cond_t *", data + 40)
@contextlib.contextmanager
def locked(alock):
assert not C.pthread_mutex_lock(alock)
try:
yield
finally:
assert not C.pthread_mutex_unlock(alock)
Wait and get awoken:
if "wait" in sys.argv:
with locked(lock):
assert not C.pthread_cond_wait(cond, lock)
elif "signal" in sys.argv:
with locked(lock):
assert not C.pthread_cond_signal(cond)
Basics of setting PTHREAD_PROCESS_SHARED
:
l = ffi.new("pthread_mutexattr_t *")
assert not C.pthread_mutexattr_init(l)
assert not C.pthread_mutexattr_setpshared(l, 1) # PTHREAD_PROCESS_SHARED
assert not C.pthread_mutex_init(lock, l)
# same for condition variable
Full code for nitpicks :-) https://github.com/dimaqq/pthread_mutexattr_init/blob/master/xsem.py based on http://linux.die.net/man/3/pthread_mutexattr_init