Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check what thread is currently doing in python

In python, is it possible to ask a thread what its currently doing? Some code might look like this:

import threading
import time
import random


def foo():
    a = 'spam'


def bar():
    if random.random() < 0.01:      # go into an infinite loop 1% of the time
        while True:
            x = 42

def run(heartbeat):
    while True:
        foo()
        bar()
        heartbeat.set()

heartbeat = threading.Event()
t = threading.Thread(target=run, args=(heartbeat, ))
t.start()

while True:
    time.sleep(1)
    if heartbeat.is_set():
        heartbeat.clear()
    else:
        print('Thread appears stuck at the following location: ')
        print(get_thread_position(t))

I'm looking to do this to monitor threads to see if they're hanging. The heartbeat event checks whether they're active and progressing normally. However, if they hang somewhere, I'd like to be able to find out where. That's where I've invented get_thread_position() which I would like to return something like a traceback to the function its currently executing. That way, I can use that information to figure out how its getting stuck in some infinite loop.

like image 681
ericksonla Avatar asked Jul 24 '17 21:07

ericksonla


1 Answers

You can use sys._current_frames() to pick up a list of top frames for each currently running thread, then find your thread in it and then inspect its frame, something like:

import sys

def get_thread_position(thread):
    frame = sys._current_frames().get(thread.ident, None)
    if frame:
        return frame.f_code.co_filename, frame.f_code.co_name, frame.f_code.co_firstlineno

This will return you a tuple with the filename, function name and line number of the function currently executing in that thread. Of course, you can pick up other frame info as well. If the thread cannot be found (i.e. died in the meantime) it will not return anything (None)

like image 86
zwer Avatar answered Oct 23 '22 07:10

zwer