2

I'd like to use a shared queue from multiple threads and modules. I have the following Python code:

# moda.py

import queue
import modb

q = queue.Queue()

def myPut(x):
    q.put(x)

def main():
    print('moda:', str(id(q)))
    modb.go()
    q.get()


if __name__ == '__main__':
    main()

and

# modb.py

import moda
import threading


def something():
    print('modb:', str(id(moda.q)))
    moda.myPut('hi')


def go():
    threading.Thread(target = something).start()

something gets called on thread 1, somethingElse gets called on thread 2. The addresses of q are different in these two methods - which is why the call to get never returns. How can I avoid this? Is it because of the cyclic import or because of multithreading?

ryyst
  • 9,563
  • 18
  • 70
  • 97
  • 1
    Cyclic imports are a bad idea in any case, and you don't seem to know the `import modb` in `moda`. – Fred Foo Aug 31 '12 at 11:32
  • `import` will prevent cyclic imports (by not importing something it already has), but mutual imports are sure to confuse the reader (i.e. you and me) – msw Aug 31 '12 at 11:33
  • @larsmans I need that import though. The modules communicate with each other. – ryyst Aug 31 '12 at 11:34
  • 1
    Could you expand this to a runnable example? – Janne Karila Aug 31 '12 at 11:35
  • 5
    See [this](http://stackoverflow.com/a/744403/302243) link for some nice info about circular imports. Specifically this info may be important `That is the reason why cyclic imports may return modules which appear to be partly empty.` You're better off having shared functionality in a third module. – Austin Phillips Aug 31 '12 at 11:39
  • 1
    @ryyst If you want modules to communicate, create a third module, import both and connect them together there. Circular dependencies are bad mkay. – bereal Aug 31 '12 at 11:40

1 Answers1

3

The link posted by Austin Phillips in the comments has the answer:

Finally, the executing script runs in a module named __main__, importing the script under its own name will create a new module unrelated to __main__.

So, __main__.q and moda.q (as imported into modb) are two different objects.

One way to make it work is to create a separate main module like this and run it instead of moda:

# modmain.py

import moda

if __name__ == '__main__':
    moda.main()

However, you should still consider putting q and other shared stuff into a new module that you import into both moda and modb to avoid some other pitfalls.

Community
  • 1
  • 1
Janne Karila
  • 24,266
  • 6
  • 53
  • 94