13

Using Python 2.7.3 on Windows.

How can I share a variable num between threads, such that, after num is squared, it is printed?

I realized that I need to understand how threads work, but docs don't have much, and I haven't found anything here either..
So, could someone explain how threads work and how to share variables between 2 threads?

My code (keeps printing 2)

import threading
def func1(num):
    while num < 100000000:
        num =  num**2
def func2(num):
    while num < 100000000:
        print num,
num = 2
thread1 = threading.Thread(target=func1,args=(num,))
thread2 = threading.Thread(target=func2,args=(num,))
print 'setup'
thread1.start()
thread2.start()
pradyunsg
  • 18,287
  • 11
  • 43
  • 96

1 Answers1

30

The general answer to this question is queues:

import threading, queue

def func1(num, q):
    while num < 100000000:
        num =  num**2
        q.put(num)

def func2(num, q):
    while num < 100000000:
        num = q.get()
        print num,

num = 2
q = queue.Queue()
thread1 = threading.Thread(target=func1,args=(num,q))
thread2 = threading.Thread(target=func2,args=(num,q))
print 'setup'
thread1.start()
thread2.start()

printing

=== pu@pumbair:~/StackOverflow:507 > ./tst.py
setup
4 16 256 65536 4294967296

Notice that in this (and your) code, num is a local variable in both func1 and func2, and they bear no relationship to each other except that they receive the initial value of the global variable num. So num is not shared here. Rather, one thread puts the value of its num into the queue, and the other binds this value to a local (and thus different) variable of the same name. But of course it could use any name.

Adrian W
  • 4,563
  • 11
  • 38
  • 52
uselpa
  • 18,732
  • 2
  • 34
  • 52
  • So, Queue is the communication mechanism between the 2 threads.. Also, a Queue can contain any data structure, Right?? – pradyunsg Mar 17 '13 at 14:40
  • 1
    Yes, a queue is a thread-safe way of communication. It can contain any data, lists, dicts, even Exceptions (which can be useful to sent back to the main process). – uselpa Mar 17 '13 at 14:48
  • Thanks for clearing my doubt.. Just a small question (before I upvote).. I can have any number of Queues (as limited by processing power). Am I correct? – pradyunsg Mar 17 '13 at 14:55
  • 2
    Sure, but generally you only need a few. For example, in a configuration with 1 producer and 100 worker threads, you only need 1 single queue where the producer puts its workload. All worker threads (which do the same thing) can get data from that one and only queue. – uselpa Mar 17 '13 at 14:57
  • 2
    I think it would be better to point out that python is call-by-value, so then you pass "num" you pass the number 2, you don't pass some kind of pointer to the number two. If you used a global, you would see the effect you're interested - then you wouldn't be passing anything into the function. – Brian Bulkowski May 13 '17 at 19:35
  • 2
    This seems to be like a push and pop style, so once you call .get(), the value won't be there anymore. It works well for putting the value for one thread to grab, but not so much if you have 2 or more thread trying to get(), because the later one will just crash. – frostshoxx Oct 10 '19 at 03:54
  • 1
    Is there a way to do it with num as a global variable? – BAKYAC Jan 06 '22 at 11:19
  • @BAKYAC https://stackoverflow.com/a/32695845/2340939 – user2340939 Sep 16 '22 at 10:48