On 2月4日, 上午2時44分, Philip Semanchuk <phi...@semanchuk.com> wrote: > On Feb 3, 2009, at 12:51 PM, Victor Lin wrote: > > > > > It seems that my program can't call to Python's function from thread > > directly, because there is Global Interpreter Lock. The python's GIL > > is so complex, I have no idea how it works. I'm sorry, what I can do > > is to ask. My question is. What should I do before and after I call a > > Python function from threads? > > Hi Victor, > I asked a similar question yesterday and have gotten no response yet > -- I hope you'll have better luck. I'm writing a C extension that > wants to implement a callback in a new thread. Here's what I think > I've learned from reading the threads API doc. Please note that this > is a classic case of the blind leading the blind! I'm sure some (most? > all?) of the ideas below are wrong, but I'm hoping that thinking > through some of this "out loud" will help both of us. Or maybe some > more knowledgeable person will take pity on/be appalled by my > ignorance and come to our rescue. =) > > Python's infamous GIL doesn't exist when a program is single-threaded. > Before a new thread is created, the main thread must call > PyEval_InitThreads() to create the GIL. However, "It is not safe to > call this function when it is unknown which thread (if any) currently > has the global interpreter lock." Therefore my extension must do this: > > i_have_the_gil = 0; > if (!PyEval_ThreadsInitialized()) { > PyEval_InitThreads(); > /* "...when this function initializes the lock, it also acquires > it." */ > i_have_the_gil = 1; > > } > > That ensures that the GIL is created. > > My extension will be calling from a newly-created C thread. The > *Python* thread doesn't exist yet; so next I have to create it. > Therefore -- > > if (!i_have_the_gil) > PyEval_AcquireLock(); > > // Might not actually be the main thread but conceptually > // it is OK to assume so here. > main_thread = PyThreadState_Get(); > > callback_thread = PyThreadState_New(main_thread->interp); > > PyThreadState_Swap(callback_thread); > > gstate = PyGILState_Ensure(); > > call_callback_function(); > > // Now unwind the above > > PyGILState_Release(gstate); > > PyThreadState_Swap(main_thread); > > PyThreadState_Clear(callback_thread); > > PyThreadState_Delete(callback_thread); > > PyEval_ReleaseLock(); > > I haven't yet tested this! But hopefully it is the right idea and just > needs a little fine tuning. > > I found this discussion > useful:http://mail.python.org/pipermail/python-list/2006-November/413088.html > > It includes the quote, "The current thread state API doc, as you read > it from top to bottom now, is in fact totally confusing for anyone who > didn't develop Python himself" > > I like! =) > > Cheers > Philip Hi Philip,
It does not work. But however, thanks your help. I have tired so many methods to do. But it crash...crash..deadlock...deadlock..crash...crash... I have no any tried success. I am going crazy. Could someone help me, thanks. -- http://mail.python.org/mailman/listinfo/python-list