Difference between revisions of "Multiprocess.Lock replacement using SYSV"
From Tech
Jump to navigationJump to searchLine 158: | Line 158: | ||
def test(l, a): |
def test(l, a): |
||
− | for i in range( |
+ | for i in range(4): |
l.acquire() |
l.acquire() |
||
− | for j in range( |
+ | for j in range(4): |
print a |
print a |
||
− | time.sleep(random.random()) |
+ | time.sleep(random.random()/30) |
print |
print |
||
l.release() |
l.release() |
||
l=Lock.Lock() |
l=Lock.Lock() |
||
Process(target=test, args=(l,"a")).start() |
Process(target=test, args=(l,"a")).start() |
||
− | Process(target=test, args=(l,"b")).start() |
+ | Process(target=test, args=(l," b")).start() |
+ | Process(target=test, args=(l," c")).start() |
||
+ | |||
</nowiki> |
</nowiki> |
Revision as of 00:29, 9 February 2013
Contents of Lock_.c
#include <Python.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int get_Lock(void){ int semid; int r; union semun { int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ }; union semun su; semid=semget(IPC_PRIVATE, 1, IPC_CREAT|0666); su.val=1; r=semctl(semid, 0, SETVAL, su); if(r==-1){ perror("semctl"); exit(1); } return semid; } void acquire(int semid){ struct sembuf sops[2]; sops[0].sem_num = 0; sops[0].sem_op = -1; sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("acquire"); exit(1); } } void release(int semid){ struct sembuf sops[2]; sops[0].sem_num = 0; /* Operate on semaphore 0 */ sops[0].sem_op = 1; /* Wait for value to equal 0 */ sops[0].sem_flg = SEM_UNDO; if (semop(semid, sops, 1) == -1) { perror("release"); exit(1); } } static PyObject * Lock_get(PyObject *self, PyObject *args); static PyObject * Lock_acquire(PyObject *self, PyObject *args); static PyObject * Lock_release(PyObject *self, PyObject *args); static PyMethodDef LockMethods[] = { {"get", Lock_get, METH_VARARGS, "get a SYSV Lock"}, {"acquire", Lock_acquire, METH_VARARGS, "acquire lock (blocks if unavailable)"}, {"release", Lock_release, METH_VARARGS, "release lock"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; static PyObject *LockError; PyMODINIT_FUNC initLock_(void) { PyObject *m; m = Py_InitModule("Lock_", LockMethods); if (m == NULL) return; LockError = PyErr_NewException("Lock_.error", NULL, NULL); Py_INCREF(LockError); PyModule_AddObject(m, "error", LockError); } static PyObject * Lock_get(PyObject *self, PyObject *args) { int semid; semid=get_Lock(); if ( semid==-1) { PyErr_SetString(LockError, "System command failed"); return NULL; } return Py_BuildValue("i", semid); } static PyObject * Lock_acquire(PyObject *self, PyObject *args) { int semid; if (!PyArg_ParseTuple(args, "i", &semid)) return NULL; acquire(semid); return Py_BuildValue(""); } static PyObject * Lock_release(PyObject *self, PyObject *args) { int semid; if (!PyArg_ParseTuple(args, "i", &semid)) return NULL; release(semid); return Py_BuildValue(""); } int main(int argc, char *argv[]) { /* Pass argv[0] to the Python interpreter */ Py_SetProgramName(argv[0]); /* Initialize the Python interpreter. Required. */ Py_Initialize(); /* Add a static module */ initLock_(); return 0; }
Contents of Lock.py
import Lock_ class Lock: def __init__(self): self.semid=Lock_.get() def acquire(self): Lock_.acquire(self.semid) def release(self): Lock_.release(self.semid)
Contents of Makefile
CFLAGS=-Wall -fPIC -I /usr/include/python2.7 #LDFLAGS=-lpython2.7 Lock_.so:Lock_.o gcc -shared Lock_.o -o Lock_.so
Contents of test.py
import Lock import time import random from multiprocessing import Process def test(l, a): for i in range(4): l.acquire() for j in range(4): print a time.sleep(random.random()/30) print l.release() l=Lock.Lock() Process(target=test, args=(l,"a")).start() Process(target=test, args=(l," b")).start() Process(target=test, args=(l," c")).start()