Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check whether a thread currently holds the GIL?

I tried to find a function that tells me whether the current thread has the global interpreter lock or not.

The Python/C-API documentation does not seem to contain such a function.

My current solution is to just acquire the lock using PyGILState_Ensure() before releasing it using PyEval_SaveThread to not try releasing a lock that wasn't acquired by the current thread.

(btw. what does "issues a fatal error" mean?)

Background of this question: I have a multithreaded application which embeds Python. If a thread is closed without releasing the lock (which might occur due to crashes), other threads are not able to run any more. Thus, when cleaning up/closing the thread, I would like to check whether the lock is held by this thread and release it in this case.

Thanks in advance for answers!

like image 825
Adrian Genaid Avatar asked Jul 06 '12 16:07

Adrian Genaid


People also ask

Does time sleep release GIL?

A thread releases the GIL when it sleeps ( time. sleep ) or when it does I/O. However, if an interval of time has passed and the thread has not released the GIL “willingly,” it will be forced to do so, thereby giving other threads the chance to run.

Does Numpy release the GIL?

According to this scipy cookbook, if you are using numpy to do array operations then Python will release the GIL, meaning that if you write your code in a numpy style, much of the calculations will be done in a few array operations, providing you with a speedup by using multiple threads.

What is the GIL and how does it affect threading?

The GIL is a single lock on the interpreter itself which adds a rule that execution of any Python bytecode requires acquiring the interpreter lock. This prevents deadlocks (as there is only one lock) and doesn't introduce much performance overhead. But it effectively makes any CPU-bound Python program single-threaded.

Does Python still have GIL?

The GIL's low performance overhead really shines for single-threaded operations, including I/O-multiplexed programs where libraries like asyncio are used, and this is still a predominant use of Python.


1 Answers

If you are using (or can use) Python 3.4, there's a new function for the exact same purpose:

if (PyGILState_Check()) {
    /* I have the GIL */
}

https://docs.python.org/3/c-api/init.html?highlight=pygilstate_check#c.PyGILState_Check

Return 1 if the current thread is holding the GIL and 0 otherwise. This function can be called from any thread at any time. Only if it has had its Python thread state initialized and currently is holding the GIL will it return 1. This is mainly a helper/diagnostic function. It can be useful for example in callback contexts or memory allocation functions when knowing that the GIL is locked can allow the caller to perform sensitive actions or otherwise behave differently.

In python 2, you can try something like the following:

int PyGILState_Check2(void) {
    PyThreadState * tstate = _PyThreadState_Current;
    return tstate && (tstate == PyGILState_GetThisThreadState());
}

It seems to work well in the cases i have tried. https://github.com/pankajp/pygilstate_check/blob/master/_pygilstate_check.c#L9

like image 130
pankaj Avatar answered Sep 18 '22 11:09

pankaj