简体   繁体   中英

Is there a way to call a method of a class object thread and have it run in that specific thread?

Context:

I have a threading class, which is called 10 times in a for loop.

For each object of the class, I pass in a username for the user which is determined by its place in the for loop, eg user0, user1, user2 ect.

I created a method called new_message() in the class, which just prints another message.

In the def run() method of the class, I added the username as key and the new_message() function as the value into a dictionary

My Problem:

I tried to call the new_message() function for one of the users, and that hopelfully the function would run in thread created for that specific user, but instead I think it ran in the main thread, causing my next lines of code to wait.

So my question is:

Is there a way to call a method of a class object thread and have it run in that specific thread?


Do note this is representation of a larger problem I have, but I have made a minimal reproduced example which mimics my code.

Code:

import time

import threading

dict = {

}

class go(threading.Thread):
    def __init__(self, username):
        threading.Thread.__init__(self)
        self.username = username

    def run(self):
        dict[self.username] = self.new_message
        for count in range(10):
            print('Hello: '+self.username+'\n')
            time.sleep(10)

    def new_message(self):
        for count in range(10):
            print('How are you: '+self.username)
            time.sleep(2)


for count in range(10):
    username = ('user' + str(count))
    go(username).start()


what_user = input('What user')
dict[what_user]()

Print('This line shouldn't be waiting to print')

Is there a way to call a method of a class object thread and have it run in that specific thread?

No this is not possible. You have already start() ed the thread, which makes it run its run() method. You cannot call a method like that to run it in that specific thread -- it'll simply run on the thread that called it as you observed (it ran in your main thread).

You need the other threads (let's call them worker threads) to be cooperative to externally submitted tasks to make this happen. For instance, you may make the worker threads listen to a work queue after doing the initial work, to pick up tasks (ie functions) and run them.

Here is a quick implementation on your code:

import time

import threading
from queue import Queue

dict = {}


class Go(threading.Thread):
    def __init__(self, username, work_queue):
        threading.Thread.__init__(self)
        self.username = username
        self.work_queue = work_queue

    def run(self):
        self.initialize()
        while True:
            task = self.work_queue.get()
            task()
            self.work_queue.task_done()

    def initialize(self):
        dict[self.username] = {"func": self.new_message, "queue": self.work_queue}
        for _ in range(10):
            print("Hello: " + self.username + "\n")
            time.sleep(10)

    def new_message(self):
        for _ in range(10):
            print("How are you: " + self.username)
            time.sleep(2)


for count in range(10):
    username = "user" + str(count)
    Go(username, Queue()).start()


what_user = input("What user")
selection = dict[what_user]
queue, method = selection["queue"], selection["func"]
queue.put(method)

print("This line shouldn't be waiting to print")

You'll observe that the "This line shouldn't be waiting to print" indeed won't wait now. Main thread puts it as a task on the queue for the chosen worker thread. The worker picks that up once it's done with its self.initialize() call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM