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)