仅在值更改时触发线程(python)

Posted

技术标签:

【中文标题】仅在值更改时触发线程(python)【英文标题】:Only trigger thread when value changes (python) 【发布时间】:2016-05-03 18:38:15 【问题描述】:

我正在研究从数据流中读取命令的东西。我被困在试图在 Python 中制作一个可重复使用的非阻塞倒计时,该倒计时可以触发触发器。所以我开始了一个小程序,只有键盘输入和一些基本的线程来计算逻辑。我找到了一些帖子,这篇帖子 (How to create a trigger with threading.Timer?) 非常有帮助。但我需要一些帮助来处理另一部分。

现在我的逻辑是这样的:“每次命令的值为 1 调用开始”

如何将我的逻辑更新为: "如果command的值为1调用start,只要command的值为1就不要再调用start。

因此,它比普通的 if/else 更像是一种值变化检测,或者我必须在某处跟踪布尔值。我只是不确定如何处理它。

#! /usr/bin/env python

import time
import threading
import random
from random import randint
import logging
from sys import argv


logging.basicConfig(level=logging.DEBUG, format='[%(levelname)s] (%(threadName)-10s) %(message)s')

def countdown(pName,command):
    print("0 countdown - command1 ".format(pName,command))
    retry = 0
    while True:
        print("0:1".format(pName,retry))
        retry += 1
        if retry > randint(5,10):
            break
        time.sleep(1)
    print("0 ended".format(pName))

def start(pName,command):
    print("starting countdown for: ",pName)
    t = threading.Thread(target=countdown,args=(pName,command))
    t.setName(pName)
    t.setDaemon(True)
    t.start()


if __name__ == "__main__":

    while 1:
        command = int(input("[1 or 2] >"))
        if command == 1:
            start("Salad",command)

        elif command == 2:
            start("Bingo",command)

现在这很粗鲁,但它只是第一次尝试解开谜题。

谢谢!

【问题讨论】:

线程在开始和结束时是否设置了标志?写入/读取简单变量是线程安全的,因此只需让主线程和子线程访问相同的标志。或者你可以使用线程锁作为你的标志。 如果你有时间,你能在下面折腾一个答案吗?当你说标志时,我在想真/假布尔值。这会起作用,但有时会变得毛茸茸。 DJ McMayhem 的回答基本上使用了内置标志,甚至更好! 我知道,它很好,只是不适用于这个特定的设置。 :-/ 我要尝试一堆布尔值,然后从那里开始。 @mishap_n 没用怎么办?我可能误解了你想要什么。如果你让我知道出了什么问题,我会更新我的答案。 【参考方案1】:

你想要函数isAlive。首先,您必须将您的线程变量移动到 main 函数,以便 main 具有适当的范围来调用 thread.isAlive()

if __name__ == "__main__":
    tSalad = threading.Thread()
    tBingo = threading.Thread()
    while 1:
        command = int(input("[1 or 2] >"))
        if command == 1 and not tSalad.isAlive():
            tSalad = threading.Thread(target = countdown, args=("Salad", 1))
            start("Salad", tSalad)

        elif command == 2 and not tBingo.isAlive():
            tBingo = threading.Thread(target = countdown, args=("Bingo", 2))
            start("Bingo", tBingo)

然后你修改你的'start'函数来接受一个线程参数:

def start(pName, t):
    print("starting countdown for: ",pName)
    t.setName(pName)
    t.setDaemon(True)
    t.start()

这应该对你有用。

【讨论】:

我知道这是对的,但我不能让这个东西生活在 main 中。数据流被拉入主函数,所有内容都被发送到辅助函数。我用 .isAlive() 尝试了一些东西,但它永远不会像死机一样触发。 @mishap_n 好吧,你必须有 something 在 main 中。我想你可以把它放在一个类中,但是你必须在 main 中保留那个类的一个对象。不管你怎么做,main 需要看到线程。

以上是关于仅在值更改时触发线程(python)的主要内容,如果未能解决你的问题,请参考以下文章

Rx.NET 中是不是存在功能类似于 BehaviorSubject 但仅在值发生更改时才发出的 Subject 实现?

Angular 手表不会在值更改时触发

ocaml,能够在值更改时触发编译错误

jQuery - 更改 iframe src 时仅在第二次单击时触发

Flutter Provider - 在值更改时调用函数而不调用 build()

v-model 更改时如何触发事件?