Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Executor - Passing function with argument as argument

My goal is to create a function that I can use to measure the execution and resource use of another function. Using a tutorial, I've create the below using Python's ThreadPoolExecutor:

from resource import *
from time import sleep
from concurrent.futures import ThreadPoolExecutor

class MemoryMonitor:
    def __init__(self):
        self.keep_measuring = True

    def measure_usage(self):
        max_usage = 0
        u_run_time = 0
        s_run_time = 0
        while self.keep_measuring:
            max_usage = max(max_usage, getrusage(RUSAGE_SELF).ru_maxrss)
            u_run_time = max(u_run_time, getrusage(RUSAGE_SELF).ru_utime) 
            s_run_time = max(s_run_time, getrusage(RUSAGE_SELF).ru_stime) 
        sleep(0.1) # run this loop every 0.1 seconds
        return [max_usage, u_run_time, s_run_time]

def execute(function):
    with ThreadPoolExecutor() as executor:
        monitor = MemoryMonitor()
        stats_thread = executor.submit(monitor.measure_usage)
        try:
            fn_thread = executor.submit(function)
            result = fn_thread.result()
            print("print result")
            print(result)
            print("print result type")
            print(type(result))
        finally:
            monitor.keep_measuring = False
            stats = stats_thread.result()
        print(stats)
        return result

def foo():
    i = 0
    while i < 3:
        print("foo")
        i+=1
    return 1

def bar(x):
    while x < 3:
        print("foobar")
        x+=1
    return 1

var = execute(foo)
print("Var = " + str(var))
var = execute(bar(0))
print("Var = " + str(var))

If I pass the function foo as an argument to the function execute, it prints the correct results and returns the value returned by foo.

If I pass the function bar in the same way, but with bar itself requiring an argument, the function runs (prints 3 times) and then I get the following error:

result = self.fn(*self.args, **self.kwargs)
TypeError: 'int' object is not callable

After some testing, the part where I'm stuck appears to be passing a function as an argument, if that function itself requires an argument. As I understand the ThreadPoolExecutor, the fn_thread object encapsulates the execution of the function submitted. The result object should simply hold the result of that execution - what am I missing that this cannot handle being passed a function with an argument?

like image 604
idalsin Avatar asked May 12 '26 07:05

idalsin


1 Answers

You are submitting

bar(0) 

instead of

bar, 0

To clarify, look at the submit's signature: submit(fn, *args, **kwargs)

the result of

bar(0)

is an integer, and the executor cannot call an integer, since it is not 'callable', as the error message suggests.

like image 152
Aleks J Avatar answered May 13 '26 22:05

Aleks J



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!