Multitasking: processes, threads, coroutines

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:

Copy code

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)
 


    

Copy code

 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:

Copy code

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)
Copy code
 
总结:
 
1 .此种创建多进程的流程
  1.自定义一个类,继承Process类
  2.实现run方法
  3.通过自定义的类,创建实例对象
  4.调用实例对象的start方法
2.对比
  自定义继承Process类的方式 比 直接创建Process对象 要稍微复杂一些,但是可以用来实现更多较为复杂逻辑的功能
3建议 
  1如果想快速的实现一个进程,功能较为简单的话,可以直接创建Process的实例对象
  2如果想实现一个功能较为完整,逻辑较为复杂的进程,可以自定义继承Process类 来实现 
 

创建进程时传递参数
 
Copy code
from multiprocessing import Process 
from time import sleep 


def test (name, age, ** kwargs): 
    for i in range (10): 
        print ('name =% s, age =% d'% (name, age)) 
        print ( kwargs) 
        sleep (0.2) 


if __name__ == '__main__': 
    p = Process (target = test, args = ('小红', 18), kwargs = {'m': 20}) 
    p.start () 
    sleep ( 1) 
    p.terminate ()   # Regardless of whether the task is completed, immediately terminate the child process 
    p.join ()   # json () will wait until the child process ends before the main process ends
Copy code
 

 

Guess you like

Origin www.cnblogs.com/wy919/p/12674889.html