The basic unit of process system for resource allocation and scheduling
The basic unit of independent scheduling and dispatching of the thread system is the smallest unit of CPU scheduling (the smallest unit of program execution flow)
Process switching requires the most resources and the lowest efficiency
Thread switching requires mediocre resources and mediocre efficiency (of course without considering GIL)
Coroutine switching task resources are small and efficient, and coroutines are also called microthreads
Depending on the number of CPU cores, multi-process and multi-thread may be parallel, but the coroutine is in one thread, so it is concurrent.
Concurrency: When multiple threads are running, if the system has only one CPU, it will be reasonably allocated to multiple threads to perform tasks, perform faster multi-allocation, slow execution less allocation.
Parallel: When the system has multiple CPUs, the threads will be allocated to different CPUs without preempting resources from each other, and can be performed simultaneously.
The biggest difference between concurrency and parallelism is whether they are simultaneous.
Multi-process: execute multiple different tasks simultaneously in the system
Multithreading: Complete multiple different tasks simultaneously in a single program
The difference
A program has at least one process, a process has at least one thread
Processes do not share global variables, threads can share global variables
The thread itself does not own system resources, it only has a little bit of resources that are essential in operation, but it can be shared with other threads belonging to the same process
Multithreading (shared global variables)
from threading import Thread
import time
def work1(nums):
nums.append(44)
print("----in work1---",nums)
def work2 (nums):
# Delay for a while to ensure that the things in the t1 thread are finished
time.sleep (1)
print ("---- in work2 ---", nums)
g_nums = [11,22,33]
t1 = Thread(target=work1, args=(g_nums,))
t1.start()
t2 = Thread(target=work2, args=(g_nums,))
t2.start()
in conclusion
Sharing global variables to all threads in one thread is convenient for multiple threads to share data, but if you modify global variables will cause confusion among multiple threads (that is, threads are not safe)
If multiple threads operate on a global variable at the same time, there will be resource competition problems, and the data result will be incorrect.
Mutex
Purpose : When multiple threads modify a certain shared data almost simultaneously, synchronous control is required
Benefits : Ensure that a piece of critical code can only be completely executed by a thread from beginning to end
Disadvantages : prevent concurrent execution of multiple threads, a certain section of code that contains locks can only be executed in single-threaded mode, the efficiency is greatly reduced, because there can be multiple locks, different threads hold different locks, and When the view acquires the lock held by the other party, it may cause a deadlock
# Create lock
mutex = threading.Lock ()
# Lock
mutex.acquire ()
# Release
mutex.release ()
Avoid deadlock
1. Try to avoid it during program design (banker's algorithm)
2. Add timeout
process
One way to create a process:
import time from multiprocessing import Process def test (): "" "The code executed separately by the child process" "" while True: print ('---- test ----') time.sleep (1) # sleep for one second Bell if __name__ == '__main__': p = Process (target = test) # passing the name of the function to the process target will specify a reference to the function p.start () # start the process is created when this sentence is executed A process # The main process executes code while True: print ('---- main ----') time.sleep (1)
to sum up:
1. By creating an additional process, you can achieve a multitasking process using a process to achieve multitasking:
2. Create a Process object, and specify a function reference by target during creation
3. When start is called, it will actually create a child process
Common methods of instance objects created by Process:
1.start (): Start a subprocess instance (create a subprocess)
2.is_live (): determine whether the child process is still alive
3.join ([timeout]): whether to wait for the end of the execution of the child process, or how many seconds to wait
terminate (): Regardless of whether the task is completed, immediately terminate the child process
The second way to create a process:
import time
from multiprocessing import Process
# 方法二:
class MyProcess(Process):
def run(self):
while True:
print('----1----')
time.sleep(1)
if __name__ == '__main__':
p = MyProcess() # 创建一个MyProcess的对象
# 当执行到这一句话的时候 会调用p.start()方法,p会先去父类中寻找start(),然后再Process的start方法中调用run方法
p.start()
while True:
print('----main----')
time.sleep(1)