LessonThis is a lesson restated in new words. Any figure in it is an example from the source, not this desk's record.

A trading check that repeats forever will never reach the next line. Python threads let two checks run on two clocks at the same time, and a shared flag lets you stop them after a set pause. Threads do not, by themselves, update one number in true parallel. The global interpreter lock, which lets only one thread run Python bytecode at a time, still serializes that update.

Why it matters

Suppose a function looks at a price and prints sell when the price is above 100, buy when it is below 90, and hold otherwise. You want that function about once a second while prices arrive. A while True loop can call it forever. time.sleep(1) inserts the one-second pause, which you can see by printing a ping above the sleep.

The loop is still one straight line of execution. Any statement placed after the loop never runs, including a later print. A second check, written as another infinite loop below the first, never starts either. If one signal should fire every second and another every five seconds, stacking loops fails for the same reason. Threads are the lecture’s way to keep both loops alive and still regain control of the program.

The idea in plain words

The standard-library threading module builds a thread from a target function. One target loops, calls the signal on a fixed price of 95, and sleeps one second. That price is between 90 and 100, so the signal says hold. The other target calls the signal on 101 and sleeps five seconds, so it says sell, and it says it on the slower clock. Creating the thread objects does nothing visible. Calling start on each one is what begins the work. After that, hold and sell both appear, on their own timing.

Stopping them takes a flag, not a restart. Two booleans begin as false. Inside each target, the global keyword is required so the function writes the module-level flag rather than a local name. Each pass checks its flag and breaks when the flag is true. The main code can sleep for ten seconds, set both flags, and then continue, for example by printing a line that proves control came back.

The lock example uses one price starting at 100. One function adds its argument. The other adds twice its argument. Called one after another with argument 1, they would show 101 and then 103 if each sees the updated price. If they truly both read 100 at the same instant, you might imagine two independent results, 101 and 102. The lecture starts both threads and prints 103. One function finished its update before the other began, because the lock held the value until the first thread was done with it. The threads did not apply two separate edits to the original 100.

How to use it

Put each repeating job in its own function. The function should do one unit of work, sleep for that job’s interval, and check a shutdown flag at the top of the loop. Build one Thread per function, pass arguments with the args tuple when the function needs them, and start every thread before you do anything that must overlap with the loops.

What usually goes wrong

Forgetting start creates thread objects and runs nothing. Forgetting global makes the flag inside the function a local variable, so the loop never sees the shutdown and you are stuck again. Setting the flag without a check inside the loop does nothing, because nothing is reading it.

Sharing a number without a plan produces the 103 surprise and then a wrong position if you believed both functions had edited the original 100. The lock is not a bug you remove with a keyword. It is how this interpreter runs Python code. Scaling a CPU-bound signal across threads will not give you extra cores.

Questions people ask

Why did the second signal never print before threads?

The first infinite loop never returns. Python runs the file from top to bottom, so a second call written below that loop is unreachable until the loop ends, and a while True loop does not end.

How do you stop the checks after ten seconds?

Sleep ten seconds on the main thread, set each shutdown flag to true, and break inside the worker when its flag is true. The program can then keep going, which the lecture showed with a print after the flags.

Why did the shared price become 103?

One thread added 1 to 100 and finished. The other then added 2 to 101. The lock kept the second thread from using 100 at the same time. Independent edits of the original 100 would have been a different experiment than the one that printed 103.