Article Index

Page 226

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#if defined(_WIN32) || defined(_WIN64)

#define SCALE 1000

#else

#define SCALE 1

#endif

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     double pi, s;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     sleep(5 * SCALE);

     Py_END_ALLOW_THREADS

     return PyFloat_FromDouble(4 * pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 227 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     int threadId;

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

Page 229 WINDOWS VERSION

example.c

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    Py_BEGIN_ALLOW_THREADS

        range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    return m;

}

 

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 231 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     PyGILState_STATE gstate = PyGILState_Ensure();

     PyObject *pimod = PyImport_AddModule("Pi");

     PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

     PyObject *myOne = PyLong_FromLong(1);

     PyObject *myInc = PyNumber_Add(myVal, myOne);

     int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

     PyGILState_Release(gstate);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     PyObject *m = PyModule_Create(&addmodule);

     if (m == NULL)

          return NULL;

     PyObject *myValue = PyLong_FromLong(42);

     PyModule_AddObject(m, "myValue", myValue);

     return m;

}

Page 233 WINDOWS VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    PyGILState_STATE gstate = PyGILState_Ensure();

    PyObject *pimod = PyImport_AddModule("Pi");

    PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

    PyObject *myOne = PyLong_FromLong(1);

    PyObject *myInc = PyNumber_Add(myVal, myOne);

    int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

    PyGILState_Release(gstate);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

         return NULL;

    Py_BEGIN_ALLOW_THREADS

    range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS

    return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    PyObject *myValue = PyLong_FromLong(42);

    PyModule_AddObject(m, "myValue", myValue);

    return m;

}

test.py

import Pi

import time

import concurrent.futures

N=10000000

print("go")

with concurrent.futures.ThreadPoolExecutor() as executor:    

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    print("do some additional work")

    print("waiting for result")

    r=f1.result()

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(r)

    print(Pi.myValue)

Page 238 LINUX VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)(state->cb), pi);

    free(state);

    return 0;

}

static void *ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    pthread_t thread1;

    pthread_create(&thread1, NULL, ComputePi, (void *)state);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 

Page 238 WINDOWS VERSION

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)state->cb, pi);

    free(state);

    return 0;

}

static int ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    int threadId;

    int *handle = CreateThread(NULL, 0, ComputePi, (void *)state, 0, &threadId);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 test.py

import Pi

import time

def myCallback(pi):

    t2 = time.perf_counter()

    print((t2-t1)*1000)

    print("python callback")

    print(pi)

N = 10000000

t1 = time.perf_counter()    

Pi.myPi(1,N,myCallback)

print("do some additional work")

while True:

    time.sleep(0.00001)