pnpnpn / timeout-decorator

Timeout decorator for Python
MIT License
628 stars 94 forks source link

Child processes outlive their parent #74

Open imidoriya opened 2 years ago

imidoriya commented 2 years ago

I'm having an issue when the main process / thread is killed (keyboard interrupt), the timeout_decorator child processes don't die with it. I have to manually kill the processes so I can restart my application properly. Is there a way to fix this? Thanks

imidoriya commented 2 years ago

Here is an example of code similar to what I"m running. However, I'm not sure this code exhibits the behavior of leaving child processes open. They seem to close fine. But my real program function is a lot more complex. Running the latest Ubuntu and Python 3.8

import time
import asyncio
import timeout_decorator
import threading

class TimesUP:
    pass

@timeout_decorator.timeout(5, use_signals=False)
def timedtest(threadnum):
    i = 1
    while True: 
        time.sleep(1)
        print(f"Thread {threadnum}: {i} seconds have passed")
        i += 1

def mytest(threadnum):
    print(f"Start {threadnum}")
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    while True:
        try:
            timedtest(threadnum)
        except timeout_decorator.TimeoutError:
                print("****** Timeout on thread %d ******" % threadnum)
    loop.close()

def consume_create():
    for i in range(5):
        jobthread = threading.Thread(
            name="ConsumerCreateThread-%d" % i,
            target=mytest,
            args=(i,),
            daemon=True,
        )
        jobthread.daemon = True
        jobthread.start()

if __name__ == '__main__':
    createthread = threading.Thread(
        name="ConsumerThread-Create",
        target=consume_create,
        daemon=True,
    )
    createthread.daemon = True
    createthread.start()
    while True:
        pass
imidoriya commented 2 years ago

I'm running into a secondary issue though with timeout-decorator that might be unworkable in my situation. My threads share objects from the parent class for storing variables, such as statistics. Currently using timeout-decorator, none of that is getting updated properly. I assume this is because the multiprocessing does not share memory and thus any updates go to a cloned object. :/

chucklesoclock commented 2 years ago

I wonder if this library should be flagged with "do not use multiprocessing with this decorator" (edit: or at least, use caution)

hashark commented 1 year ago

I have the same issue... @imidoriya if you found a solution please share it.

In the meantime I'm going to try the solution in this fork: https://github.com/woshihaoren/timeout-decorator (and this PR: https://github.com/pnpnpn/timeout-decorator/pull/52) I'll update here if it helped

thanks!