简体   繁体   English

你如何在线程中的函数之间共享数据 python

[英]How do you share data between functions in threads with python

I Have a counting function that I would like to start and restart while getting the live variables to use in another function my problem is while using threading it seams like even global variables don't seem to work to pass variables around.我有一个计数 function 我想启动并重新启动,同时让实时变量在另一个 function 中使用我的问题是在使用线程时它接缝就像全局变量似乎无法传递变量一样。 What I want the code to do is have a counter be triggered as needed or maybe free running I'm not sure yet.我想让代码做的是根据需要触发一个计数器,或者我不确定是否可以自由运行。 To be able to reset the counter and get the value of the counter.能够重置计数器并获取计数器的值。

Right now the counter will start and run fine but the print_stuff function keeps telling me that there is no attribute countval .现在计数器将启动并运行良好,但print_stuff function 一直告诉我没有属性countval

The count thread gets started at startup but I don't necessarily want it to start up immediately, I would like to trigger it as needed but I cant put count_thread.start() twice or it will through a error so I'm calling the thread at startup and then calling the function again to restart it as needed.计数线程在启动时启动,但我不一定希望它立即启动,我想根据需要触发它,但我不能将count_thread.start()放入两次,否则它会出错,所以我调用启动时的线程,然后再次调用 function 以根据需要重新启动它。 Maybe there is a more elegant way of doing that.?也许有一种更优雅的方式来做到这一点。?

import threading
import time

def count():
    global countval
    for countval in range(3):
        print('looping')
        time.sleep(1)

def print_stuff():
    global countval
    e = input("press enter to start")
    count()
    while True:
         if countval == 3:
             print("time out")

count_thread = threading.Thread(target=count)
print_thread = threading.Thread(target=print_stuff)

print_thread.start()
count_thread.start()

print_stuff is getting to the if statement before the count function is able to create the variable. print_stuffcount function 能够创建变量之前进入if语句。 Just do them in the opposite order.只需按相反的顺序进行即可。 Either that, or create a global countval = 0 to start things off.要么,要么创建一个全局countval = 0来开始。

To solve the no attribute problem you can use Queue , and if you want to stop your counting thread you can set a global variable or you can pass a function (using lambda or inner function or...) to do that.要解决无属性问题,您可以使用Queue ,如果您想停止计数线程,您可以设置一个全局变量,或者您可以传递一个 function(使用lambdainner function或...)来做到这一点。

Here is one way to do that:这是一种方法:

import threading
import time
from queue import Queue

from typing import Callable


def count(q, stop_counting):
    # type: (Queue, Callable[[], bool]) -> None

    for countval in range(3):

        if stop_counting():
            print('stopped')
            break

        print(f'looping {countval}')
        q.put(countval)

        time.sleep(1)


def print_stuff(q):
    # type: (Queue) -> None
    while True:
        countval = q.get()

        print(f'countval gotten: {countval}')

        if countval == 3:
            print("time out")


def main():
    flag_stop_counting = False
    q = Queue()

    def stop_counting():
        return flag_stop_counting

    count_thread = threading.Thread(target=count, args=(q, stop_counting,))
    print_thread = threading.Thread(target=print_stuff, args=(q,))

    print_thread.start()
    count_thread.start()

    time.sleep(1.25)
    flag_stop_counting = True


if __name__ == '__main__':
    main()


In this code:在这段代码中:

  • counter checks if it should stop counting or not counter检查是否应该停止计数
  • counter puts the value that it made to q counter将它的值q
  • print_stuff get the value from q (Note: he waits until counter puts his value in q ) print_stuffq获取值(注意:他等到计数器将他的值放入q

To check that program works:要检查程序是否有效:

  • after 1.25 seconds we change the value of flag_stop_counting 1.25 秒后我们更改flag_stop_counting的值

But if you want your counter to only have a for, i guess it's better to don't make it as a thread and run it whenever you want.但是如果你想让你的计数器只有一个for,我想最好不要把它作为一个线程并在你想要的时候运行它。

Hope it was helpful.希望对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM