Home > Enterprise >  How to start another thread without waiting for function to finish?
How to start another thread without waiting for function to finish?

Time:11-23

Hey I am making a telegram bot and I need it to be able to run the same command multiple times at once.

dispatcher.add_handler(CommandHandler("send", send))

This is the command ^

And inside the command it starts a function:

sendmail(email, amount, update, context)

This function takes around 5seconds to finish. I want it so I can run it multiple times at once without needing to wait for it to finish. I tried the following:

Thread(target=sendmail(email, amount, update, context)).start()

This would give me no errors but It waits for function to finish then proceeds. I also tried this

with ThreadPoolExecutor(max_workers=100) as executor:
            executor.submit(sendmail, email, amount, update, context).result()

but it gave me the following error:

No error handlers are registered, logging exception.
Traceback (most recent call last):
  File "C:\Users\seal\AppData\Local\Programs\Python\Python310\lib\site-packages\telegram\ext\dispatcher.py", line 557, in process_update
    handler.handle_update(update, self, check, context)
  File "C:\Users\seal\AppData\Local\Programs\Python\Python310\lib\site-packages\telegram\ext\handler.py", line 199, in handle_update
    return self.callback(update, context)
  File "c:\Users\seal\Downloads\telegrambot\main.py", line 382, in sendmailcmd
    executor.submit(sendmail, email, amount, update, context).result()
  File "C:\Users\main\AppData\Local\Programs\Python\Python310\lib\concurrent\futures\thread.py", line 169, in submit
    raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown

CodePudding user response:

This is my first attempt at threading, but maybe try this:

import threading
x1 = threading.Thread(target=sendmail, args=(email, amount, update, context))
x1.start()

You can just put the x1 = threading... and x1.start() in a loop to have it run multiple times

Hope this helps

CodePudding user response:

It's not waiting for one function to finish, to start another, but in python GIL (Global Interpreter Lock) executes only one thread at a given time. Since thread use multiple cores, time between two functions are negligible in most cases.

Following is the way to start threads with the ThreadPoolExecutor, please adjust it to your usecase.

def async_send_email(emails_to_send):
        with ThreadPoolExecutor(max_workers=32) as executor:
            futures = [
                executor.submit(
                    send_email,
                    email=email_to_send.email,
                    amount=email_to_send.amount,
                    update=email_to_send.update,
                    context=email_to_send.context
                )
                for email_to_send in emails_to_send
            ]

        for future, email_to_send in zip(futures, emails_to_send):
            try:
                future.result()
            except Exception as e:
                # Handle the exceptions.
                continue

def send_email(email, amount, update, context):
    # do what you want here.
  • Related