Hi,

I've worked the past few days on a stastistical sampling profiling tool for an online Python 2.7 service that runs on Windows.

My approach so far is:
- I have a dedicated thread that sleeps most of the time and wakes up every n-th milliseconds. - Whenever the thread wakes-up, it gets the current frame/callstack for all the active threads (using threading.enumerate()) and increments an occurence counter for each currently executed code path. - When enough time has passed, all the collected samples are saved for analysis.

This works somehow, but I fear this technique isn't aligned with how threading works in Python where only one thread can run Python code at a given time (GIL).

Consider the following case:

- An application has 2 threads running.
- Thread A sleeps for 30 seconds.
- Thread B does some heavy computation (only Python code).

In this case, it is fairly obvious that most of the process execution time will be spent in thread B, which will likely have the GIL most of the time (since thread A is sleeping). However, when measuring the activity with the technique mentionned above, the sleep instruction in Thread B appears as the most costly code location, has it is present in every profiling sample.

I'd like to modify my approach above by only measuring the activity of the last active thread. Obviously, this is not as simple as calling `threading.current_thread()` because it will always give me the profiling thread which is currently executing.

Is there a way to know which thread had the GIL right before my profiling thread acquired it ? Perhaps through a C extension ? I've seen such profilers for Linux that take advantage of an ITIMER signal to do that. Sadly this is not an option on Windows.

Any feedback or remark concerning my technique is also welcome.

Thanks,

Julien.

-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to