embedded python and windows multi threading, can't get it to work

freesteel zabaione at uk2.net
Tue Jun 13 14:11:40 EDT 2006


I am trying to run a python programme embedded from C++. I want to run
the same python code concurrently in several threads. I read the manual
on embedding, especially chapter 8, and searched for relevant info on
google all afternoon, but I can't get this to work. What am I doing
wrong? I use python2.4 and vc++7 (.net). The first thread seems to work
okay, the 2nd thread crashes, but the exception information is not very
useful:
(An unhandled exception of type 'System.NullReferenceException'
occurred in pyembed_test.exe

Additional information: Object reference not set to an instance of an
object.)

Here is a simplified example, it is heavily based on this article:
http://www.codeproject.com/cpp/embedpython_1.asp



#include <afxwin.h>
#include <Python.h>
#include <Windows.h>
#include <process.h>

#define USE_AFX 0




#if USE_AFX
UINT MyThread(LPVOID lpParam)
#else
void MyThread(void* lpParam)
#endif
{
	Py_Initialize();
//#if 0
//	PyEval_InitThreads();
	PyThreadState *mainthreadstate = PyThreadState_Get();
	PyInterpreterState *maininterpreterstate = mainthreadstate->interp;
        PyThreadState *mythreadstate =
PyThreadState_New(maininterpreterstate);
	PyEval_ReleaseLock();
	PyEval_AcquireLock();
	PyThreadState *tmpstate = PyThreadState_Swap(mythreadstate);
//#endif


	int* num = (int *)lpParam;
	int ret = 0;
	ret = PyRun_SimpleString("x = []");
	ret = PyRun_SimpleString("for i in range(10):\n  x.append(i)");
	char cmd[100];
	sprintf(cmd, "f = open('test%d.txt', 'w')", *num);
	ret = PyRun_SimpleString(cmd);
	ret = PyRun_SimpleString("f.write('%s' % x.__str__())");
	ret = PyRun_SimpleString("f.close()");

//#if 0
	PyThreadState_Swap(tmpstate);
	PyEval_ReleaseLock();
	PyThreadState_Clear(mythreadstate);
	PyThreadState_Delete(mythreadstate);
//#endif



	Py_Finalize();
#if USE_AFX
	return 0;
#else
	_endthread();
#endif
}

class CMyWinApp : public CWinApp
{
public:
	CMyWinApp() { }
	BOOL InitInstance()
	{
		int num0 = 0, num1 = 1;
		HANDLE hnd0, hnd1;
#if USE_AFX
		CWinThread* pThread0 = AfxBeginThread(MyThread, &num0);
		hnd0 = pThread0->m_hThread;
		CWinThread* pThread1 = AfxBeginThread(MyThread, &num1);
		hnd1 = pThread1->m_hThread;
#else
		hnd0 = (HANDLE) _beginthread(MyThread, 0, &num0);
		hnd1 = (HANDLE) _beginthread(MyThread, 0, &num1);
#endif

		// wait for the worker thread to terminate.
		WaitForSingleObject(hnd0, INFINITE);
		WaitForSingleObject(hnd1, INFINITE);

		return TRUE;
	};
};

CMyWinApp app;




More information about the Python-list mailing list