Why does Python _multiprocessing.SemLock have a name?
My environment
- Python 2.7.3
- Ubuntu 14.04
- Source code I'm using: CPython on GitHub
Additional information to understand my question
As far as my understanding is concerned, Modules/_multiprocessing/semaphore.c
implements the internal Python SemLock object that is used to implement multiprocessing.synchronize.SemLock
in the Python standard library:
class SemLock(object):
def __init__(self, kind, value, maxvalue, *, ctx):
(...A lot of other code...)
sl = self._semlock = _multiprocessing.SemLock( # <-- Here.
Modules/_multiprocessing/semaphore.c
implements this internal SemLock object by defining a SemLockObject in C and exporting it as a SemLock in Python.
Here is the definition of C:
typedef struct {
PyObject_HEAD
SEM_HANDLE handle;
unsigned long last_tid;
int count;
int maxvalue;
int kind;
char *name; /* <--- It has 'name'. */
} SemLockObject;
Later SemLockObject is exported as SemLock, in Line # 617 :
PyTypeObject _PyMp_SemLockType = {
PyVarObject_HEAD_INIT(NULL, 0)
/* tp_name */ "_multiprocessing.SemLock",
/* tp_basicsize */ sizeof(SemLockObject),
Several _semlock_members_ are also exported with SemLock, including "name". See Line # 608 :
static PyMemberDef semlock_members[] = {
{"handle", T_SEM_HANDLE, offsetof(SemLockObject, handle), READONLY,
""},
{"kind", T_INT, offsetof(SemLockObject, kind), READONLY,
""},
{"maxvalue", T_INT, offsetof(SemLockObject, maxvalue), READONLY,
""},
{"name", T_STRING, offsetof(SemLockObject, name), READONLY,
""}, /* <--- Here it is. */
{NULL}
};
Therefore, there is reason to believe that at runtime I can access the name element . However, when I check the members of this internal SemLock object, I do not see the name member . Here is my verification code:
import multiprocessing as mp
import inspect
lock = mp.Semaphore(1)
members = inspect.getmembers(lock._semlock)
for (name, _) in members:
print name
Here's the result:
SEM_VALUE_MAX
__class__
__delattr__
__doc__
__enter__
__exit__
__format__
__getattribute__
__hash__
__init__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
_after_fork
_count
_get_value
_is_mine
_is_zero
_rebuild
acquire
handle <-- 'handle' is defined in 'semlock_members'
kind <-- 'kind' is defined in 'semlock_members'
maxvalue <-- 'maxvalue' is defined in 'semlock_members'
release
But where is the name ??
In fact, if we look at multiprocessing.synchronize.SemLock.__init__
Line # 76 , it checks the value _semlock.name
:
if self._semlock.name is not None:
which makes me think the base _semlock has a 'name' member because otherwise the code would throw an exception such as an AttributeError object: '_multiprocessing.SemLock' has no 'name' attribute. "
I must have missed something. Can anyone help me point this out?
source to share