about blocking the main thread
error usage for join
Thread.Join () acts as a blocking main thread, that is, when the child thread is not returned, the main thread waits for it to return and then continues execution.
Join cannot be used with start in loops
The following is an error code that creates 5 threads and then activates the thread with a loop that blocks the main thread after activation.
threads = [Thread () for I in range (5)] for
Thread in Threads:
thread.start ()
Thread.Join ()
Execution process:
1. In the first cycle, thread 1 is activated by the main thread through the start function, and thread 1 is evaluated.
2. Because the start function does not block the main thread, while thread 1 is operating, the main thread executes the join function down.
3. After the join is performed, the primary thread is blocked by thread 1, and the main thread cannot perform the next round until thread 1 returns the result.
4. After the thread 1 calculation is complete, the blocking of the main thread is lifted.
5. The main thread enters the next round loop, activates thread 2 and is blocked by it ...
In this way, it can be seen that the five threads that should have been concurrent have become sequential queues, and the efficiency is no different from that of a single thread. the correct use of join
Use two loops to process the start and join functions separately. You can implement concurrency.
threads = [Thread () for I in range (5)] for
thread in Threads:
Thread.Start () for
thread in threads:
threa D.join ()
Time.sleep instead of join for debugging
Previously seen in some projects such code, using Time.sleep instead of join manual blocking main thread.
The main thread is caught in a wireless loop and cannot exit until all child threads return.
For thread in Threads:
Thread.Start () while
1:
If Thread_num = 0:
break
time.sleep (0.01)
about the thread lock (threading. Lock)
does a single core Cpu+pil still need a lock?
Non-atomic operations count = count + 1 is theoretically thread-unsafe.
Use 3 threads to do the same at the same time change the value of the global variable count and view the results of the program execution.
If the result is correct, there is no thread conflict.
Use the following code to test
#-*-Coding:utf-8-*-
Import Threading
Import time
count = 0
class Counter (threading. Thread):
def __init__ (self, name):
self.thread_name = name
super (Counter, self). __init__ (Name=name)
def run (self):
global count for
I in Xrange (100000):
count = count + 1
counters = [Counter (' THR ead:%s '% i) for I in range (5)] for
counter in counters:
Counter.start ()
time.sleep (5)
print ' count= %s '% count
Run Result: count=275552
In fact, each run results are different and incorrect, which proves that single core Cpu+pil still cannot guarantee thread safety and need to be locked.
Lock the correct code after:
#-*-Coding:utf-8-*-
Import Threading
Import time
count = 0
lock = Threading. Lock ()
class Counter (threading. Thread):
def __init__ (self, name):
self.thread_name = name
Self.lock = Threading. Lock ()
super (Counter, self). __init__ (name=name)
def run (self):
global Count
global lock
for I in Xrange (100000):
lock.acquire ()
count = count + 1
lock.release ()
counters = [Counter (' thread:% S '% i) for-I in range (5)] for
counter in counters:
Counter.start ()
time.sleep (5)
print ' count=%s '% c Ount
Result: count=500000 attention to the overall importance of the lock
This is a simple Python syntax problem, but it can be ignored when the logic is complex.
To ensure that the lock is common to multiple child threads, do not create a lock inside the thread's subclass.
The following is an error code
#-*-coding:utf-8-*-Import Threading Import Time count = 0 # lock = Threading. Lock () # The correct declaration position class Counter (threading. Thread): Def __init__ (self, name): Self.thread_name = name Self.lock = Threading. Lock () # False Declaration location super (Counter, self). __init__ (Name=name) def run (self): global count for I I n xrange (100000): Self.lock.acquire () Count = count + 1 self.lock.release () counters = [Counter (' thread:%s '% i) for I in range (5)] for Counter in Counters:print counter.thread_name Counter.start ( ) Time.sleep (5) print ' count=%s '% count