pyinstrument icon indicating copy to clipboard operation
pyinstrument copied to clipboard

Support multithreaded profiling

Open georgeharker opened this issue 1 year ago • 5 comments

Thanks for pyintrument - it's incredibly useful

I had need to trace a multithreaded python app and examine the relationship between threads. Obviously in some cases multithreading can be a little interesting in python, but in this particular case works well.

I have extended a fork of pyinstrument to support showing all child threads from the one where profiling starts. I get nice results with all threads separated which has been hugely helpful.

I'll file a PR and reference this issue. It's still a bit of a WIP, but i'd be curious to see if it looks reasonable to you.

georgeharker avatar Dec 04 '24 23:12 georgeharker

This would definitely be a great feature to have in pyinstrument.

As a workaround until/if this feature gets picked up, I've come up with the following hack to automatically profile newly spawned threads by (ab)using threading.settrace, here's an implementation of this hack in one of my projects.

One can detect when a thread has started, and start the profiler when threading.settrace calls the tracing function with Threading.run() in its frame argument with the call event. The profiler can be stopped when the same Threading.run() is encountered in the trace function with a return event. You need to keep track of the number of times Threading.run() is called, as a thread can spawn other threads.

I had to use settrace instead of setprofile as pyinstrument uses setprofile, and overrides the custom profiling function with its own.

lucamuscat avatar Dec 28 '24 11:12 lucamuscat

Take a look at the referenced PR - it does much of that but also allows viewing the timelines of all threads together.

georgeharker avatar Dec 28 '24 15:12 georgeharker

@georgeharker I've already had a look, I need to dedicate some time on integrating it with my project.

My biggest issue with the PR in its current state is that the majority of tests are failing, there are some missing updates to the Session class in various methods, and the linters seem to be complaining.

Changing the return type for the Profiler from a list of frames to a dictionary seems like a tough breaking change. Maybe this multi threading aware code can be placed into its own class, leaving us with two kinds of profilers?

lucamuscat avatar Dec 28 '24 18:12 lucamuscat

Yeah there's still work to do there for sure! Just did enough for my needs and wanted some feedback about what it would look like to get it into a state for merge

georgeharker avatar Dec 28 '24 18:12 georgeharker

+1

iguy0 avatar Mar 15 '25 15:03 iguy0