Thread programming
-1. Basic concepts of thread
1. What's the matter
- Threads are called lightweight processes
- Threads can also use computer multi-core resources, which is a multitasking programming method
- Threads are the smallest unit of system allocation kernel
- A thread can be understood as a branch task of a process
2. Thread characteristics
- A process can contain multiple threads
- Thread is also a running behavior, consuming computer resources
- All threads in a thread share the resources of the process
- The operation of multiple threads does not affect each other
- The creation and destruction of threads consume far less resources than processes
- Each thread also has its own ID and other characteristics
0. Creating threads by threading module
1. Create thread object
from threading import Thread t = Thread() function: Create thread object parameter: target Binding thread function args Tuples pass parameters to thread function locations kwargs The dictionary passes parameters to thread function keys
2. Start thread
t.start()
3. Recycle thread
t.join([timeout])
4. Code demonstration
""" thread1.py Thread based usage step: 1. Encapsulating thread functions 2.Create thread object 3.Start thread 4.Recycle thread """ import os from threading import Thread from time import sleep a = 1 # Thread function def music(): for i in range(3): sleep(2) print('play:Yellow River Chorus %s' % os.getpid()) global a print("a,",a) a = 1000 # Create thread object t = Thread(target=music) # Start thread t.start() for i in range(3): sleep(1) print('play:beauty love %s' % os.getpid()) # Recycle thread t.join() print('Program end') print("a,", a)
5. Thread object properties
-
t.name thread name
-
t.setName() sets the thread name
-
t.getName() get thread name
-
t.is_alive() to see if the thread is in the lifecycle
-
t.daemon sets the main thread and branch thread to exit, and branch thread also exits To set before start, it is usually not used with join
-
Code demonstration
""" thread3.py Thread properties demo """ from threading import Thread from time import sleep def fun(): sleep(3) print('Thread property test') t = Thread(target=fun, name='ceshi') # When the main thread exits, the branch thread also exits. It must be used before start. It is meaningless to join t.setDaemon(True) t.start() print(t.getName()) t.setName('Tedu') print('is alive:', t.is_alive()) print('daemon', t.daemon)
6. Custom thread class
- Create step
- Inherit Thread class
- Rewrite__ init__ Method to add its own properties, and use super to load the parent class properties
- Override run method
- usage method
- Instantiate object
- Call start to automatically execute the run method
- Call join recycle thread
Code demonstration
""" Custom thread class example """ from threading import Thread # Custom thread class class ThreadClass(Thread): # Override parent init def __init__(self, *args, **kwargs): self.attr = args[0] # Load parent init super().__init__() # Assume that many steps are required to complete the function def f1(self): print('1') def f2(self): print(2) # Override run logic call def run(self): self.f1() self.f2() t = ThreadClass() t.start() t.join()
7. A very important exercise I don't understand a lot
from threading import Thread from time import sleep, ctime class MyThread(Thread): def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): super().__init__() self.fun = target self.args = args self.kwargs = kwargs def run(self): self.fun(*self.args, **self.kwargs) def player(sec, song): for i in range(3): print("Playing %s : %s" % (song, ctime())) sleep(sec) t = MyThread(target=player, args=(3,), kwargs={'song': 'Quantity'}) t.start() t.join()
8. Inter thread communication
-
Communication method
- Global traversal is used to communicate between threads
-
Competition for shared resources
- Shared resources: resources that can be operated by multiple processes or threads are called shared resources, and the operation code segment of shared resources is called critical area
- Impact: disorderly operation of public resources may lead to data confusion or operation errors At this time, it is often necessary to coordinate the operation order by the synchronous mutual exclusion mechanism
-
Synchronous mutual exclusion mechanism
- Synchronization: synchronization is a cooperative relationship. In order to complete the operation, multiple processes or threads form a coordination and execute the operation in order according to the necessary steps
2. Mutual exclusion: mutual exclusion is a constraint relationship. When a process or thread occupies a resource, it will be locked. At this time, other process threads cannot operate the resource until it is unlocked
## 9. Thread synchronization and mutual exclusion method
1. Thread Event code demonstration
from threading import Event # Create thread event object e = Event() # Blocking wait e is set e.wait([timeout]) # Set e to make wait end blocking e.set() # Return e to unset state e.clear() # Check whether the current e is set e.is_set()
""" event Thread mutual exclusion method demonstration """ from threading import Event, Thread s = None # For communication e = Event() def yzr(): print('Yang Zirong came to worship the mountain') global s s = 'Heavenly King covering the earth tiger' e.set() #Finished sharing resource e settings t = Thread(target=yzr) t.start() print('You're right. The password is your own') e.wait() #Blocking wait e.set() if s == 'Heavenly King covering the earth tiger': print('pagoda will stop river monster') print('Confirmed the eyes,You are the right person') e.clear() else: print('Kill him...') t.join() print('Program end')
2. Thread Lock code demonstration
from threading import Lock lock = Lock()Create lock object lock.acquire() Lock if lock It will be blocked if it is locked and called again lock.release() Unlock with lock: Lock .... .... with Code block unlock automatic unlock
""" thread_lock Thread lock demo """ from threading import Thread, Lock a = b = 0 lock = Lock() def value(): while True: # Lock lock.acquire() print('a=%d,b=%d' % (a, b)) if a != b else print('a Not equal to b') # Unlock lock.release() t = Thread(target=value) t.start() while True: # with start locking with lock: a += 1 b += 1 # with unlock automatic unlock t.join() print('Program end')
10. Deadlock and its handling
1. Definitions
Deadlock is a blocking phenomenon caused by two or more threads competing for resources or communicating with each other during execution. Without external force, they will not be able to move forward At this time, it is said that the system is in a deadlock state or the system has a deadlock
2. Illustration
3. Deadlock generation conditions
Necessary conditions for deadlock occurrence
- Mutually exclusive condition: refers to the exclusive use of the allocated resources by the thread, that is, a resource is occupied by only one process within a period of time. If there are other processes requesting resources at this time, the requester can only wait until the process occupying the resources is released.
- Request and hold condition: refers to that the thread has held at least one resource, but puts forward a new resource request, and the resource has been occupied by other processes. At this time, the requesting thread is blocked, but it still holds the other resources it has obtained.
- No deprivation condition: the resources obtained by the thread cannot be deprived before they are used up, and can only be released by itself when they are used up. Generally, CPU memory resources can be forcibly allocated and deprived by the system.
- Loop waiting condition: when a deadlock occurs, there must be a thread resource ring chain, that is, t0 in the process set {T0, T1, T2, ···, Tn} is waiting for a resource occupied by T1; T1 is waiting for resources occupied by T2,..., Tn is waiting for resources occupied by t0.
Causes of deadlock
In short, the causes of deadlock can be summarized into three sentences:
- The current thread has resources required by other threads
- The current thread waits for resources already owned by other threads
- Do not give up their own resources
- How to avoid deadlock
Deadlock is a phenomenon we don't want to see. We should try our best to avoid deadlock. By setting some restrictions to destroy one or more of the four necessary conditions for deadlock, deadlock can be prevented. Deadlock prevention is an easy method to implement. However, the restrictions imposed are often too strict, which may lead to the utilization of system resources.
Deadlock code demonstration
from time import sleep from threading import Thread, Lock # Transaction class class Account: def __init__(self, _id, balance, lock): # user self._id = _id # deposit self.balance = balance # lock self.lock = lock # Withdraw money def withdraw(self, amount): self.balance -= amount # save money def deposit(self, amount): self.balance += amount # balance def get_balance(self): return self.balance Tom = Account('Tom', 5000, Lock()) Alex = Account('Alex', 8000, Lock()) def transfer(from_, to, amount): # Lock your account if from_.lock.acquire(): # Account decrease from_.withdraw(amount) sleep(0.5) if to.lock.acquire(): to.deposit(amount) to.lock.release() from_.lock.release() print('Transfer completed %s to%s transfer accounts%d' % (from_._id, to._id, amount)) # transfer(Tom, Alex, 1000) t1 = Thread(target=transfer, args=(Tom, Alex, 2000)) t2 = Thread(target=transfer, args=(Alex, Tom, 3500)) t1.start() t2.start() t1.join() t2.join() print('Program end')