Поток не будет выполняться в фоновом режиме?

#python #multithreading #python-multithreading

#python #многопоточность #python-многопоточность

Вопрос:

Когда я вызываю my_batch.run_jobs() , мой поток не запускается в фоновом режиме. Вместо этого он выполняется синхронно, ожидая завершения выполнения метода.

Для контекста я вызываю этот метод из .py файла, а метод находится внутри класса. Когда я запускаю те же функции за пределами этого файла / класса, он работает в фоновом режиме просто отлично.

 # package_name/module_name.py


class BaseModel(Model):
    class Meta:
        database = get_db()


class Batch(BaseModel):

    def run_jobs():
        
        def sleeper():
            sleep(999)
        
        t = threading.Thread(target=sleeper)
        #t.daemon = True #tried with/ without
        t.start()
  

например

 my_batch = Batch()
my_batch.run_jobs()
#doesn't print until line above finishes
print("in progress")
  

Ответ №1:

Я обновил ваш код для тестирования. Кажется, он работает так, как ожидалось.

 import time, threading

class BaseModel(): pass
#    class Meta:
#        database = get_db()

class Batch(BaseModel):

    def run_jobs(self):
        
        def sleeper(): # runs in background thread
            for t in range(10):
               print('<sleeper>', t)
               time.sleep(.9)
        
        t = threading.Thread(target=sleeper)
        t.start()
        
        # this runs same time as background thread (sleeper)
        for t in range(10):
           print('<rj>', t)
           time.sleep(.8)
                
mybatch = Batch()
mybatch.run_jobs()  # runs in main thread

# this loop runs after run_jobs completes
for t in range(5):
   print('<main>', t)
   time.sleep(1)
  

Вывод

 <sleeper> 0
<rj> 0
<rj> 1
<sleeper> 1
<rj> 2
<sleeper> 2
<rj> 3
<sleeper> 3
<rj> 4
<sleeper> 4
<rj> 5
<sleeper> 5
<rj> 6
<sleeper> 6
<rj> 7
<sleeper> 7
<rj> 8
<rj> 9
<sleeper> 8
<main> 0
<sleeper> 9
<main> 1
<main> 2
<main> 3
<main> 4
  

— Обновить —

Вот тот же код, разделенный на модули:

— mike.py

 import time, threading

class BaseModel(): pass
#    class Meta:
#        database = get_db()

class Batch(BaseModel):

    def run_jobs(self):
        
        def sleeper(): # runs in background thread
            for t in range(10):
               print('<sleeper>', t)
               time.sleep(.9)
        
        t = threading.Thread(target=sleeper)
        t.start()
        
        # this runs same time as background thread (sleeper)
        for t in range(10):
           print('<rj>', t)
           time.sleep(.8)
  

— threadchk.py (основной сценарий)

 import mike
import time, threading
    
mybatch = mike.Batch()
mybatch.run_jobs()  # runs in main thread

# this loop runs after method completes
for t in range(5):
   print('<main>', t)
   time.sleep(1)
  

Вывод такой же, как и при предыдущем запуске

Комментарии:

1. Спасибо, Майк. Не могли бы вы поместить класс в mike.py и делая import mike это my_batch = mike.Batch() , вы хотите посмотреть, получаете ли вы по-прежнему то же самое?

2. Спасибо. Теперь знайте, что на самом деле это должно работать именно так.