多任务:进程、线程、协程

进程 系统进行资源分配和调度的基本单位

线程 系统独立调度和分派的基本单位 ,是CPU调度的最小单位(程序执行流的最小单元)

进程切换需要的资源最大,效率最低

线程切换需要的资源一般,效率一般(当然在不考虑GIL的情况下)

协程切换任务资源很小,效率高,协程又称微线程

多进程、多线程根据cpu核数不一样可能是并行的,但是协程是在一个线程中,所以是并发。

并发:当多个线程在运行时,如果系统只有一个CPU,它会合理分配给多个线程去执行任务,执行快的多分配,执行慢的少分配。

并行:当系统有多个CPU时, 线程会分配到不同CPU,互不抢占资源,可以同时进行。

并发和并行最大的区别就在于,是否同时。

多进程:在系统同时执行多个不同的任务

多线程:在单一程序中同时完成多个不同的任务

 

区别点

一个程序至少有一个进程 一个进程至少有一个线程

进程不共享全局变量,线程可以共享全局变量

线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享

 

多线程(共享全局变量)


from threading import Thread
import time

def work1(nums):
nums.append(44)
print("----in work1---",nums)


def work2(nums):
#延时一会,保证t1线程中的事情做完
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()

结论

在一个线程内对所有线程共享全局变量,很方便多个线程共享数据,但是如果修改全局变量会造成多线程之间的混乱(即线程非安全)

如果多个线程同时对一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确。

 

 

互斥锁

目的:当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制

好处:确保了某段关键代码只能由一个线程从头到尾完整地执行

坏处:阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了,由于可以存在多个所锁,不同的线程持有不同的锁,并视图获取对方持有的锁时,可能会造成死锁

# 创建锁
mutex = threading.Lock()

# 锁定
mutex.acquire()

# 释放
mutex.release()

避免死锁

1、程序设计时尽量避免(银行家算法)

2、添加超时时间

 

进程

创建进程的方式一:

复制代码

import time
from multiprocessing import Process


def test():
    """子进程单独执行的代码"""
    while True:
        print('----test----')
        time.sleep(1)  # 睡眠一秒钟


if __name__ == '__main__':
    p = Process(target=test)  # 把函数的名字传到进程中 target会指定一个函数的引用
    p.start()  # 开启进程 当这句话执行时才创建了一个进程
    # 主进程执行代码
    while True:
        print('----main----')
        time.sleep(1)

复制代码

 总结:

1.通过额外创建一个进程,可以实现多任务使用进程实现多任务的流程:

2.创建一个Process对象,且在创建时通过target指定一个函数的引用

3.当调用start时,会真正的创建一个子进程

Process创建的实例对象的常用办法:

1.start():启动子进程实例(创建子进程)

2.is_live():判断子进程是否还在活着

3.join([timeout]):是否等待子进程执行结束,或等待多少秒

terminate():不管任务是否完成,立即终止子进程

 

 

创建进程的方式二:

复制代码

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

创建进程时传递参数
 
复制代码
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()  # 不管任务是否完成,立即终止子进程
    p.join()  # json()会等到子进程结束后主进程才会结束
复制代码
 

 

posted @ 2020-04-10 18:04  .未央  阅读(175)  评论(0编辑  收藏  举报