0

I've been looking into a way to directly change variables in a running module. What I want to achieve is that a load test is being run and that I can manually adjust the call pace or whatsoever.

Below some code that I just created (not-tested e.d.), just to give you an idea.

class A():
    def __init__(self):
        self.value = 1
    def runForever(self):
        while(1):
            print self.value
    def setValue(self, value):
        self.value = value

if __name__ == '__main__':
    #Some code to create the A object and directly apply the value from an human's input
    a = A()

    #Some parallelism or something has to be applied.
    a.runForever()
    a.setValue(raw_input("New value: "))

Edit #1: Yes, I know that now I will never hit the a.setValue() :-)

2 Answers2

0

The pseudo code you wrote is quite similar to the way Threading / Multiprocessing works in python. You will want to start a (for example) thread that "runs forever" and then instead of modifying the internal rate value directly, you will probably just send a message through a Queue that gives the new value.

Check out this question.

Here is a demonstration of doing what you asked about. I prefer to use Queues to directly making calls on threads / processes.

import Queue  # !!warning. if you use multiprocessing, use multiprocessing.Queue
import threading
import time


def main():
    q = Queue.Queue()
    tester = Tester(q)
    tester.start()
    while True:
        user_input = raw_input("New period in seconds or (q)uit: ")
        if user_input.lower() == 'q':
            break
        try:
            new_speed = float(user_input)
        except ValueError:
            new_speed = None  # ignore junk
        if new_speed is not None:
            q.put(new_speed)
    q.put(Tester.STOP_TOKEN)

class Tester(threading.Thread):
    STOP_TOKEN = '<<stop>>'
    def __init__(self, q):
        threading.Thread.__init__(self)
        self.q = q
        self.speed = 1
    def run(self):
        while True:
            # get from the queue
            try:
                item = self.q.get(block=False)  # don't hang
            except Queue.Empty:
                item = None  # do nothing
            if item:
                # stop when requested
                if item == self.STOP_TOKEN:
                    break  # stop this thread loop
                # otherwise check for a new speed
                try:
                    self.speed = float(item)
                except ValueError:
                    pass  # whatever you like with unknown input
            # do your thing
            self.main_code()
    def main_code(self):
        time.sleep(self.speed)  # or whatever you want to do


if __name__ == '__main__':
    main()
Community
  • 1
  • 1
KobeJohn
  • 7,390
  • 6
  • 41
  • 62
0

Here is a multi-threaded example. This code will work with the python interpreter but not with the Python Shell of IDLE, because the raw_input function is not handled the same way.

from threading import Thread
from time import sleep

class A(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.value = 1
        self.stop_flag = False

    def run(self):
        while not self.stop_flag:
            sleep(1)
            print(self.value)

    def set_value(self, value):
        self.value = value

    def stop(self):
        self.stop_flag = True


if __name__ == '__main__':
    a = A()
    a.start()
    try:
        while 1:
            r = raw_input()
            a.set_value(int(r))
    except:
        a.stop()
Vincent
  • 12,919
  • 1
  • 42
  • 64