python3 multiprocessing Semaphore

http://mirror.hust.edu.cn/gnu/glibc/

glibc-2.29.tar.gz

glibc: bits/semaphore.h

#if __WORDSIZE == 64

# define __SIZEOF_SEM_T 32

#else

# define __SIZEOF_SEM_T 16

#endif

/* Value returned if `sem_open' failed. */

#define SEM_FAILED ((sem_t *) 0)

typedef union

{

char __size[__SIZEOF_SEM_T];

long int __align;

} sem_t;

PyModule_AddObject(module, "SemLock", (PyObject*)&_PyMp_SemLockType);

Python-3.6.8/Modules/_multiprocessing/multiprocessing.h

typedef sem_t *SEM_HANDLE;

Python-3.6.8/Modules/_multiprocessing/semaphore.c

enum { RECURSIVE_MUTEX, SEMAPHORE };

typedef struct {

PyObject_HEAD

SEM_HANDLE handle;

long last_tid;

int count;

int maxvalue;

int kind;

char *name;

} SemLockObject;

/*

* Semaphore methods

*/

static PyMethodDef semlock_methods[] = {

{"acquire", (PyCFunction)semlock_acquire, METH_VARARGS | METH_KEYWORDS,

"acquire the semaphore/lock"},

{"release", (PyCFunction)semlock_release, METH_NOARGS,

"release the semaphore/lock"},

{"__enter__", (PyCFunction)semlock_acquire, METH_VARARGS | METH_KEYWORDS,

"enter the semaphore/lock"},

{"__exit__", (PyCFunction)semlock_release, METH_VARARGS,

"exit the semaphore/lock"},

{"_count", (PyCFunction)semlock_count, METH_NOARGS,

"num of `acquire()`s minus num of `release()`s for this process"},

{"_is_mine", (PyCFunction)semlock_ismine, METH_NOARGS,

"whether the lock is owned by this thread"},

{"_get_value", (PyCFunction)semlock_getvalue, METH_NOARGS,

"get the value of the semaphore"},

{"_is_zero", (PyCFunction)semlock_iszero, METH_NOARGS,

"returns whether semaphore has value zero"},

{"_rebuild", (PyCFunction)semlock_rebuild, METH_VARARGS | METH_CLASS,

""},

{"_after_fork", (PyCFunction)semlock_afterfork, METH_NOARGS,

"rezero the net acquisition count after fork()"},

{NULL}

};

/*

* Member table

*/

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,

""},

{NULL}

};

/*

* Semaphore type

*/

PyTypeObject _PyMp_SemLockType = {

PyVarObject_HEAD_INIT(NULL, 0)

/* tp_name */ "_multiprocessing.SemLock",

/* tp_basicsize */ sizeof(SemLockObject),

/* tp_itemsize */ 0,

/* tp_dealloc */ (destructor)semlock_dealloc,

/* tp_print */ 0,

/* tp_getattr */ 0,

/* tp_setattr */ 0,

/* tp_reserved */ 0,

/* tp_repr */ 0,

/* tp_as_number */ 0,

/* tp_as_sequence */ 0,

/* tp_as_mapping */ 0,

/* tp_hash */ 0,

/* tp_call */ 0,

/* tp_str */ 0,

/* tp_getattro */ 0,

/* tp_setattro */ 0,

/* tp_as_buffer */ 0,

/* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

/* tp_doc */ "Semaphore/Mutex type",

/* tp_traverse */ 0,

/* tp_clear */ 0,

/* tp_richcompare */ 0,

/* tp_weaklistoffset */ 0,

/* tp_iter */ 0,

/* tp_iternext */ 0,

/* tp_methods */ semlock_methods,

/* tp_members */ semlock_members,

/* tp_getset */ 0,

/* tp_base */ 0,

/* tp_dict */ 0,

/* tp_descr_get */ 0,

/* tp_descr_set */ 0,

/* tp_dictoffset */ 0,

/* tp_init */ 0,

/* tp_alloc */ 0,

/* tp_new */ semlock_new,

};

static PyObject *

semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)

{

等等的实现

multiprocessing/synchronize.py

class SemLock(object):

def __init__(self, kind, value, maxvalue, *, ctx):

if ctx is None:

ctx = context._default_context.get_context()

name = ctx.get_start_method()

unlink_now = sys.platform == 'win32' or name == 'fork'

for i in range(100):

try:

sl = self._semlock = _multiprocessing.SemLock(

kind, value, maxvalue, self._make_name(),

unlink_now)

class Semaphore(SemLock):

def __init__(self, value=1, *, ctx):

SemLock.__init__(self, SEMAPHORE, value, SEM_VALUE_MAX, ctx=ctx)