This article mainly introduces Python multi-thread programming (4): Using Lock mutex Lock. This article describes the concept of mutex Lock, synchronous blocking, sample code, and so on, for more information, see the preceding example. Python: Use the threading module to implement multi-threaded programming. two methods: thread initiation and Python: Use the threading module to implement multi-threaded programming. important functions of the Thread class. the examples in these two articles demonstrate independent threads that are independent from each other. now we consider the following question: assume that each Thread needs to access the same public resource, how should we write our code?
The code is as follows:
'''
Created on 2012-9-8
@ Author: walfred
@ Module: thread. ThreadTest3
'''
Import threading
Import time
Counter = 0
Class MyThread (threading. Thread ):
Def _ init _ (self ):
Threading. Thread. _ init _ (self)
Def run (self ):
Global counter
Time. sleep (1 );
Counter + = 1
Print "I am % s, set counter: % s" % (self. name, counter)
If _ name _ = "_ main __":
For I in range (0,200 ):
My_thread = MyThread ()
My_thread.start ()
To solve the problem above, we may write such code. we assume that we run 200 threads, but these 200 threads will access the public resource counter, and process the resource (counter + = 1). The code looks like this, but let's look at the running result:
The code is as follows:
I am Thread-69, set counter: 64
I am Thread-73, set counter: 66I am Thread-74, set counter: 67I am Thread-75, set counter: 68I am Thread-76, set counter: 69I am Thread-78, set counter: 70I am Thread-77, set counter: 71I am Thread-58, set counter: 72I am Thread-60, set counter: 73I am Thread-62, set counter: 74I am Thread-66, set counter: 75I am Thread-70, set counter: 76I am Thread-72, set counter: 77I am Thread-79, set counter: 78I am Thread-71, set counter: 78
I only pasted a part of the print results, from which we can see that the global resource (counter) is preemptible. The cause of the problem is that the access to the same resource by multiple threads is not controlled, the data is damaged, making the running results of the thread unpredictable. This phenomenon is called "thread unsafe ". In the development process, we must avoid this situation. how can we avoid it? This uses the mutex lock we mentioned in the summary.
Mutex lock concept
In Python programming, the concept of object mutex lock is introduced to ensure the integrity of shared data operations. Each object corresponds to a tag that can be called a mutex lock. this tag is used to ensure that only one thread can access the object at any time. In Python, we use the Lock class provided by the threading module.
The above program is rectified. Therefore, we need to add a mutex variable mutex = threading. lock (), and we will first seize the Lock mutex before competing for resources. acquire (), after the resource is used, we release the lock mutex. release (). The code is as follows:
The code is as follows:
'''
Created on 2012-9-8
@ Author: walfred
@ Module: thread. ThreadTest4
'''
Import threading
Import time
Counter = 0
Mutex = threading. Lock ()
Class MyThread (threading. Thread ):
Def _ init _ (self ):
Threading. Thread. _ init _ (self)
Def run (self ):
Global counter, mutex
Time. sleep (1 );
If mutex. acquire ():
Counter + = 1
Print "I am % s, set counter: % s" % (self. name, counter)
Mutex. release ()
If _ name _ = "_ main __":
For I in range (0,100 ):
My_thread = MyThread ()
My_thread.start ()
Synchronization blocking
When a thread calls the acquire () method of the Lock object to obtain the Lock, the Lock enters the "locked" state. Because only one thread 1 can obtain the lock at a time, if another thread 2 tries to obtain the lock at this time, the thread 2 will change to the "blo synchronization blocking state. The lock enters the "unlocked" state after the release () method of thread 1 that owns the lock is called. The thread scheduler selects one of the threads in the synchronous blocking state to obtain the lock and enters the running state.
Further consideration
By using mutex lock on public resources, we can achieve our goal simply, but if we encounter the following situation:
In case of lock nesting, what should we do? this nesting means that when a thread acquires critical resources, it needs to be acquired again;
If there are multiple public resources, when multiple resources are shared among threads, if the two threads occupy a part of resources and wait for the other resources at the same time;
The above two cases will directly cause program suspension, that is, deadlocks. next we will talk about deadlocks and reentrant locks RLock.