Skip to content

threading.join does not work correctly with parameter timeout #127665

@EgodPrime

Description

@EgodPrime

Bug report

Bug description:

The documentation of threading.join says 'When the timeout argument is present and not None, it should be a floating-point number specifying a timeout for the operation in seconds (or fractions thereof). '

So I try use this feature to create a time-limit execution decorator like this:

def time_limit_execution(timeout_seconds: float,):
    def wrap(func):
        def to_do(*args, **kwargs):
            def run():
                func(*args, **kwargs)
            t = threading.Thread(target=run)
            try:
                t.start()
                t.join(timeout_seconds)
                if t.is_alive():
                    raise TimeoutError(f"Execution takes more than {timeout_seconds:.2f} seconds")
            except Exception as e:
                raise e
        return to_do
    return wrap

At the beginning, it works well for my other code. Util I meet this one:

@time_limit_execution(0.1)
def func():
    return 2**1000000000
   
func()

I notice that this code takes much more than 0.1 second, and I try to directly evaluate whether it is a bug by the following:

import threading
import time

def func1():
    time.sleep(20)

def func2():
    return 2**1000000000

th = threading.Thread(target=func1)
t0 = time.time()
th.start()
th.join(1)
dt = time.time()-t0
print(f"dt of func1 is {dt}")
assert dt > 1
assert dt < 2

th = threading.Thread(target=func2)
t0 = time.time()
th.start()
th.join(1)
dt = time.time()-t0
print(f"dt of func2 is {dt}")
assert dt > 1
assert dt < 2

which ouputs (Also replayed in Google Colab):

dt of func1 is 1.0007781982421875
dt of func2 is 10.11729907989502
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
[<ipython-input-1-8d922cdc60b7>](https://localhost:8080/#) in <cell line: 26>()
     24 print(f"dt of func2 is {dt}")
     25 assert dt > 1
---> 26 assert dt < 2

AssertionError:

I tried reading the source to figure out if there are some limits about threading.join, which points to _thread._ThreadHandle.join used in cpython/Lib/threading.py, implemented in cpython/Modules/_threadmodule.c, but the C code is too complex for me to understand.

So I wonder know whether it is a bug and whether it will be fixed soon.

CPython versions tested on:

3.9, 3.10, 3.11, 3.12, 3.13

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions