0

I played around with thread in Python 3x. Below is my code.

import threading

def hello_world2():
  threading.Timer(7.0, hello_world2).start()
  print("22222222!")

def hello_world():
  threading.Timer(5.0, hello_world).start()
  print("Hello, World!")

hello_world2()
hello_world()

However, I am surprised with the output printed because it has two possible scenarios for output that I observed.
First one is

Hello, World!
22222222!
Hello, World!
22222222!
Hello, World!
Hello, World!
22222222!

It printed out Hello, World! first while in my code I specifically wrote to print 22222222! first.

The second scenario is

22222222!
Hello, World!Hello, World!
22222222!
Hello, World!
22222222!
Hello, World!
Hello, World!
22222222!

Although it printed 22222222! first, it didn't start a new line before printing the second Hello, World! on the second line.

So, I want to know what's happened here to cause this kind of behaviour and will I be able to control it to make it behave the way I intend it to do.

NOTE: My question doesn't primarily focus on printing but rather asking about a general behavior of multithreaded programme. If I use multiple threads, would my programme have a dodgy or undesirable sequence of execution? Would this kind of strange behaviour exist even if I don't print out (compared to run a single thread)

Thank you.

bensw
  • 2,818
  • 5
  • 21
  • 31
  • Possible duplicate of [How do I get a thread safe print in Python 2.6?](https://stackoverflow.com/questions/3029816/how-do-i-get-a-thread-safe-print-in-python-2-6) – anthony sottile Sep 22 '17 at 02:10
  • may be hard to see from the title / question of that linked duplicate but the answer essentially equates to ["because print isn't thread safe as it's implemented with two opcodes"](https://stackoverflow.com/a/3029854/812183). Here's an [example disassembly](https://i.fluffy.cc/b4xzhS2NrQGrB2S0827b6017F6k0lZbv.html#L6-7) – anthony sottile Sep 22 '17 at 02:13
  • "If I use multiple threads, would my programme have a dodgy or undesirable sequence of execution?": yes, and no. Depends on what you call undesirable. Other than the newline issue, both of the above print-outs are completely acceptable (and expected) to me. If there are no so for you, please indicate what output you expect. –  Sep 22 '17 at 04:09
  • @AnthonySottile Interesting to know. But whatever happened to that other newline? That seems to have been completely discarded, but how? –  Sep 22 '17 at 04:11
  • @Evert oops didn't notice you tagged [python-3.x] (I'm actually unable to reproduce in python3.6 which implements `print()` as a function call (and therefore holds the GIL the whole time)) -- what platform and exact version are you using? – anthony sottile Sep 22 '17 at 04:32
  • @Anthony Sottile I use PyCharm Community Edition 2017.1.4 on Windows 10. This is getting more interesting if it also depends on the environment as I use this as dev env but it will be tested in lunux container on Ubuntu as same as the production env. – bensw Sep 22 '17 at 04:56
  • @Evert this is just my experiment. What I actually want to use it for is to grab some stuff from the servers and put the results in database. That is what I'm going to use it for. – bensw Sep 22 '17 at 04:58
  • That's actually not my question. My question is: do you really care about the order of the output (where the two threads coincidence with their timer)? –  Sep 22 '17 at 05:09
  • @Evert I don't know just yet. I may because i'm thinking that when two threads try to write to DB one will be successful while the other one is locked out. – bensw Sep 22 '17 at 05:35
  • Ah, but database are slightly different beasts. Yes, the database will (should) lock one thread if they're writing to the database. But the other thread will just write once the first thread is done and the database removes the lock. So you'd get both entries into the database. –  Sep 22 '17 at 06:10

0 Answers0