0

2 つの異なる Python の質問から得た回答を組み合わせようとしています。

これが最初の質問と回答です。基本的に、2 つのスレッドを生成したかっただけです。1 つは powerDown() に、もう 1 つは powerUp() に、powerUp() は powerDown() で保留されます。

Pythonで同じオブジェクトの別のスレッド内にスレッドを生成する方法は?

import threading

class Server(threading.Thread):
    # some code
    def run(self):
        self.reboot()

    # This is the top level function called by other objects
    def reboot(self):
        # perhaps add a lock
        if not hasattr(self, "_down"):
            self._down = threading.Thread(target=self.__powerDown)
            self._down.start()
            up = threading.Thread(target=self.__powerUp)
            up.start()

    def __powerDown(self):
        # do something

    def __powerUp(self):
        if not hasattr(self, "_down"):
            return
        self._down.join()
        # do something
        del self._down

これが2番目の質問と回答です。基本的には、スレッドを開始してから、オブジェクトの関数を呼び出したいと考えていました。

実行中の Python スレッドで関数を呼び出す方法

import queue
import threading

class SomeClass(threading.Thread):
    def __init__(self, q, loop_time = 1.0/60):
        self.q = q
        self.timeout = loop_time
        super(SomeClass, self).__init__()

    def onThread(self, function, *args, **kwargs):
        self.q.put((function, args, kwargs))

    def run(self):
        while True:
            try:
                function, args, kwargs = self.q.get(timeout=self.timeout)
                function(*args, **kwargs)
            except queue.Empty:
                self.idle()

    def idle(self):
        # put the code you would have put in the `run` loop here 

    def doSomething(self):
        pass

    def doSomethingElse(self):
        pass

これが結合されたアイデアコードです。基本的には、スレッドを生成してから、実行する関数 (この場合は reboot()) をキューに入れたいと考えていました。次に、reboot() は、powerDown() スレッドと powerUp() スレッドの 2 つのスレッドを作成します。ここで、powerDown() は powerUp() を保留します。

import threading
import Queue

class Server(threading.Thread):
    def __init__(self, q, loop_time = 1.0/60):
        self.q = q
        self.timeout = loop_time
        super(Server, self).__init__()

    def run(self):
        while True:
            try:
                function, args, kwargs = self.q.get(timeout=self.timeout)
                function(*args, **kwargs)
            except queue.Empty:
                self.idle()

    def idle(self):
        # put the code you would have put in the `run` loop here 

    # This is the top level function called by other objects
    def reboot(self):
        self.__onthread(self.__reboot)

    def __reboot(self):
        if not hasattr(self, "_down"):
            self._down = threading.Thread(target=self.__powerDown)
            self._down.start()
            up = threading.Thread(target=self.__powerUp)
            up.start()

    def __onThread(self, function, *args, **kwargs):
        self.q.put((function, args, kwargs))

    def __powerDown(self):
        # do something

    def __powerUp(self):
        if not hasattr(self, "_down"):
            return
        self._down.join()
        # do something
        del self._down

2 つのサーバー サブクラスを作成する場合を除いて、すべて動作します。

class ServerA(Server):
    pass

class ServerB(Server):
    pass

両方のサブクラスを開始し、start() 関数と再起動関数を呼び出すコードは次のとおりです。

serverA = ServerA(None)
serverB = ServerB(None)
serverA.start()
serverB.start()
serverA.reboot()
serverB.reboot()

serverA.reboot() と serverB.reboot() が同時に発生することを期待していますが、これは私が望んでいることですが、そうではありません! serverB.reboot() は、serverA.reboot() の実行後に実行されます。つまり、printステートメントを入れると、

serverA started
serverB started
serverA.reboot() called
serverA.__powerDown called
serverA.__powerUp called
serverB.reboot() called
serverB.__powerDown called
serverB.__powerUp called

ServerAの再起動には時間がかかるという事実を知っているので、このようなことを期待しています

serverA started
serverB started
serverA.reboot() called
serverB.reboot() called
serverA.__powerDown called
serverB.__powerDown called
serverB.__powerUp called
serverA.__powerUp called

それが理にかなっていることを願っています。もしそうなら、reboot() 関数が同時に実行されないのはなぜですか?

4

1 に答える 1