Запустите метод объекта в потоке демона в python - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь смоделировать среду с помощью vms и пытаюсь запустить метод объекта в фоновом потоке.Мой код выглядит следующим образом.

файл hyper_v.py:

import random
from threading import Thread
from virtual_machine import VirtualMachine

class HyperV(object):
def __init__(self, hyperv_name):
    self.hyperv_name = hyperv_name
    self.vms_created = {}

def create_vm(self, vm_name):
    if vm_name not in self.vms_created:
        vm1 = VirtualMachine({'vm_name': vm_name})
        self.vms_created[vm_name] = vm1
        vm1.boot()
    else:
        print('VM:', vm_name, 'already exists')

def get_vm_stats(self, vm_name):
    print('vm stats of ', vm_name)
    print(self.vms_created[vm_name].get_values())

if __name__ == '__main__':
    hv = HyperV('temp')
    vm_name = 'test-vm'
    hv.create_vm(vm_name)
    print('getting vm stats')
    th2 = Thread(name='vm1_stats', target=hv.get_vm_stats(vm_name) )
    th2.start()

файл virtual_machine.py в том же каталоге:

import random, time, uuid, json 
from threading import Thread

class VirtualMachine(object):
def __init__(self, interval = 2, *args, **kwargs):
    self.vm_id = str(uuid.uuid4())
    #self.vm_name = kwargs['vm_name']
    self.cpu_percentage = 0
    self.ram_percentage = 0
    self.disk_percentage = 0
    self.interval = interval

def boot(self):
    print('Bootingup', self.vm_id)
    th = Thread(name='vm1', target=self.update() )
    th.daemon = True      #Setting the thread as daemon thread to run in background
    print(th.isDaemon())  #This prints true 
    th.start()

def update(self):
    # This method needs to run in the background simulating an actual vm with changing values. 
    i = 0 
    while(i < 5 ): #Added counter for debugging, ideally this would be while(True) 
        i+=1 
        time.sleep(self.interval)
        print('updating', self.vm_id)
        self.cpu_percentage = round(random.uniform(0,100),2)
        self.ram_percentage = round(random.uniform(0,100),2)
        self.disk_percentage = round(random.uniform(0,100),2)

def get_values(self):
    return_json = {'cpu_percentage': self.cpu_percentage,
                   'ram_percentage': self.ram_percentage,
                   'disk_percentage': self.disk_percentage}
    return json.dumps(return_json)

Идея заключается в создании потока, который продолжает обновлятьзначения и по запросу, мы читаем значения объекта vm, вызывая vm_obj.get_values ​​(), мы будем создавать несколько vm_objects для имитации нескольких параллельно работающих vms, и нам нужно получить информацию от конкретного vm по запросу.

Проблема, с которой я сталкиваюсь, заключается в том, что функция update () vm не работает в фоновом режиме (даже если поток установлен как поток демона).

Вызов метода hv.get_vm_stats (vm_name) ожидает завершения vm_object.update () (который вызывается vm_object.boot ()) и затем печатает статистику.Я хотел бы получить статистику vm по запросу, оставив vm_object.update () работать в фоновом режиме навсегда.

Пожалуйста, поделитесь своими мыслями, если я упускаю из виду все, что связано с основами.Я попытался разобраться в проблемах, связанных с библиотекой потоков Python, но не смог прийти к какому-либо заключению.Любая помощь очень ценится.Следующие шаги будут иметь API REST для вызова этих функций для получения данных любого виртуального компьютера, но я поражен этой проблемой.

Заранее спасибо,

1 Ответ

0 голосов
/ 28 февраля 2019

Как отметил @Klaus D в комментариях, моя ошибка заключалась в использовании фигурных скобок при указании целевой функции в определении потока, что привело к немедленному вызову функции.

target = self.update () вызовет метод сразу.Удалите (), чтобы передать метод потоку, не вызывая его.

...