来源:https://awasu.com/weblog/embedding-python/threads/
没有经过测试
主线程代码
void
main( int argc , char** argv )
{
// initialize Python
Py_Initialize() ;
PyEval_InitThreads() ; // nb: creates and locks the GIL
// NOTE: We save the current thread state, and restore it when we unload,
// so that we can clean up properly.
PyThreadState* pMainThreadState = PyEval_SaveThread() ; // nb: this also releases the GIL
// create some worker threads
vector<HANDLE> workerThreads ;
for ( int i=0 ; i < 5 ; ++i )
{
HANDLE h = CreateThread( NULL , 0 , workerThread , (LPVOID)i , 0 , NULL ) ;
assert( h != NULL ) ;
workerThreads.push_back( h ) ;
}
// wait for the worker threads to finish
DWORD rc = WaitForMultipleObjects( workerThreads.size() , &workerThreads[0] , TRUE , INFINITE ) ;
assert( rc == WAIT_OBJECT_0 ) ;
// clean up
PyEval_RestoreThread( pMainThreadState ) ; // nb: this also locks the GIL
Py_Finalize() ;
}
子线程代码
DWORD WINAPI
workerThread( LPVOID threadParam )
{
// initialize
int threadNo = (int)threadParam ;
// create a new interpreter
PyEval_AcquireLock() ; // nb: get the GIL
PyThreadState* pThreadState = Py_NewInterpreter() ;
assert( pThreadState != NULL ) ;
PyEval_ReleaseThread( pThreadState ) ; // nb: this also releases the GIL
// do some Python stuff
for ( int i=0 ; i < 5 ; ++i )
{
// switch in our interpreter
PyEval_AcquireThread( pThreadState ) ;
// execute some Python
stringstream buf ;
buf << "print \"Thread " << threadNo << ": pass " << 1+i << "\"" ;
int rc = PyRun_SimpleString( buf.str().c_str() ) ;
assert( rc == 0 ) ;
// switch out our interpreter
PyEval_ReleaseThread( pThreadState ) ;
// sleep for a short time
Sleep( rand() % 100 ) ;
}
// release the interpreter
PyEval_AcquireThread( pThreadState ) ; // nb: this also locks the GIL
Py_EndInterpreter( pThreadState ) ;
PyEval_ReleaseLock() ; // nb: release the GIL
return 0 ;
}