0

So this is my scenario. I have a python script that runs in an infinite while loop which takes in user input.

But I now want another function to to do stuff every n seconds while the main loop, which is blocking (waiting for python's input() function), is still running. I have looked into asyncio and scheduling but they don't seem to work with blocking function calls, or am I mistaking?

I have looked into multiprocessing but couldn't wrap my head around how exactly I would be supposed to do that yet.

EDIT:

if __name__ == "__main__":
    def survivor():
        count = 5
        while count:
            print("alive")
            time.sleep(8)
            count -= 1
        print("done")


    test = JobChainClient()

    cli = threading.Thread(name="cli", target=test.getShell())
    network = threading.Thread(name="network", target=survivor())

    cli.start()
    network.start()
    print("Done")

This code gets my CLI which is a infinite while loop and my network daemon. When I run this it obviously works but the problem is this:

(JobChain) > exit
Closing JobChain client now!
alive
alive
alive

My loop breaks after the exit command and only than does the other thread start, I probably just missed something here, please correct me.

2 Answers 2

1

The simplest solution is to call this other function (that does stuff every n seconds) in a separate thread.

If you want to use asyncio, look into aioconsole which provides the async equivalent of input().

EDIT
Regarding the updated question, the correct way to start a thread is:

# note the lack of parentheses after `getShell` - you only
# want to refer to the function, not to call it (yet)
cli = threading.Thread(name="cli", target=test.getShell)
cli.start()
Sign up to request clarification or add additional context in comments.

3 Comments

I tried the thread approach but Im running into GIL. Which makes sense, since my CLI is blocking so no way to run another thread in the meantime. I also looked into multiprocessings Process but that disables stdin so thats not an alternative for me. But aioconsole seems to be a way, though I still would like to know a way around that, for understanding purposes.
@huhnmonster The GIL shouldn't affect you, because Python releases it on all blocking calls. Maybe you should post another question with a minimal reproducible example of the threading approach failing for you.
Added the example in my question.
0

You cannot synchronously block on user input. Every blocking = blocking thread which is supposed to handle your other requests in meanwhile.

For maximum gain from asynchronous programming pattern you have to use async everywhere.

Main idea is to have an event loop where no tasks are blocking. Tasks should just ASAP return some kind of promise that it will be fulfilled with return value sometime in the future. Then eventloop can continue and handle your next tasks immediately.

If you really need synchronous blocking, you should spawn new thread to do cpu intensive bound task.

1 Comment

I dont really have the problem that my task is CPU-heavy, but rather that I dont seem to find a way to get thread x to run parallel to my cli which is the problem I am facing. I obviously get what you mean with the event loop needing non-blocking function calls, but that was more of me just being stupid, async is not the solution for my problem, I apologise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.