Home > Mobile >  How do you share data between functions in threads with python
How do you share data between functions in threads with python

Time:10-06

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. 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.

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. 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()

CodePudding user response:

print_stuff is getting to the if statement before the count function is able to create the variable. Just do them in the opposite order. Either that, or create a global countval = 0 to start things off.

CodePudding user response:

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.

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 puts the value that it made to q
  • print_stuff get the value from q (Note: he waits until counter puts his value in q)

To check that program works:

  • after 1.25 seconds we change the value of 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.

Hope it was helpful.

  • Related