Multiprocess.Lock replacement using SYSV

From Tech
Revision as of 01:13, 9 February 2013 by 77.72.146.250 (talk) (Created page with "Contents of <tt>Lock_.c</tt> <nowiki>#include <Python.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int get_Lock(void){ int semid; int r; union semu…")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

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);
  }
}

void p(int semid, int i){
  int j;
  
  acquire(semid);
  for(j=0; j<10; j++){
    printf("%i\n",i);
    sleep(1);
  }
  release(semid);
}


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;

}