You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.2 KiB

多任务介绍

什么是多任务? 操作系统可以同时执行多个任务

现在的操作系统:windows mac linux unix 这些操作系统 都支持多任务

单核CPU如何实现多任务 表面看,每个任务都是同时执行,实际上是每个任务在轮询着执行,只是因为CPU的调度太快导致我们感觉像是所有任务都在同时执行

多核CPU如何实现多任务? 是真正实现了多个任务同时执行

并发看上去一起执行任务数大于CPU核心数 并行一起执行任务数必须小于等于CPU核心数

实现多任务的方式: 1、多进程方式
2、多线程方式 3、协程方式 4、多进程+多线程

没有多进程

import time
def func():
    while True:
        print("this is a process2")
        time.sleep(1.5)
if __name__ == '__main__':
    while True:
        print("this is a process1")
        time.sleep(1)
    func()

multiprocessing 多进程

from multiprocessing import Process
import time,os

def func(str):

#os.getpid  获取当前进程的进程号

#os.getppid  获取当前进程的父进程

    while True:
        print("this is process 2--%s--%s--%s"%(str,os.getpid(),os.getppid()))
        time.sleep(1.5)

if __name__ == '__main__':
    print("父进程启动...--%s--%s"%(os.getpid(),os.getppid()))
    # 创建子进程
    # target 说明进程的任务
    p = Process(target=func,args=("python",))
    # 启动进程
    p.start()
    # 主进程中的
    while True:
        print("this is a process 1--%s--%s"%(os.getpid(),os.getppid()))
        time.sleep(1)


让父进程等待子进程结束之后父进程再结束

from multiprocessing import Process
from time import sleep

def func():
    print("子进程启动...")
    sleep(3)
    print("子进程结束...")

if __name__ == '__main__':
    print("父进程启动...")
    p = Process(target = func)
    p.start()
    # sleep(1)
    # 让父进程等待子进程结束之后父进程再结束
    # timeout 超时时间   父进程的等待时间
    p.join()
    #执行后一直等待
    print("父进程结束...")

在子进程中修改全局变量 对父进程中的全局变量没有影响

from multiprocessing import Process
num = 100
def run1():
    print("孙子进程开始...")
    print("孙子进程结束...%s"%(num))

def run():
    print("子进程开始...")
    global num
    num += 1
    print(num)
    p = Process(target=run1)
    p.start()
    p.join()
    print("子进程结束...")

if __name__ == '__main__':
    print("父进程开始...")
    p = Process(target=run)
    p.start()
    p.join()
    num += 2
    # 在子进程中修改全局变量  对父进程中的全局变量没有影响
    # 我们在创建子进程的时候  对全局变量做了一个备份
    # 子进程和父进程的Num是两个完全不同的变量
    # 所有进程对全局变量的修改  都不会影响其它进程
    print("父进程结束...%d"%(num))

进程池

from multiprocessing import Pool,Process
import time,random
def foo():
    print("孙子进程开始...")
    print("孙子进程结束...")
def func(__name__):
    print("子进程%s启动..."%(__name__))
    start = time.time()
    time.sleep(random.choice([1,2,3]))
    end = time.time()
    print("子进程%s结束...耗时%.2f"%(__name__,end - start))

if __name__ == '__main__':
    print("父进程开始...")
    # 创建进程池
    # 如果没有参数  默认大小为自己电脑的CPU核心数
    # 表示可以同时执行的进程数量
    pp = Pool(2)
    for i in range(4):
        # 创建进程,放入进程池统一管理
        pp.apply_async(func,args=(i,))
        # 在调用join之前必须先关掉进程池
    # 进程池一旦关闭  就不能再添加新的进程了
    pp.close()
    # 进程池对象调用join,会等待进程池中所有的子进程结束之后再结束父进程
    pp.join()
    print("父进程结束...")

多线程:

在一个进程内部,要同时干很多事,就需要同时执行多个子任务 那么我们把进程内的这些子任务叫做线程

线程的内存空间是共享的 每个线程都共享同一个进程的资源

模块: 1、_thread模块 低级模块 2、threading模块 高级模块 对_thread模块进行了封装 """

创建线程

import threading,time

def run(num):
    print("子线程%s开始..."%(threading.current_thread().__name__))
    time.sleep(2)
    print(num)
    time.sleep(2)
    # current_thread  返回一个当前线程的实例
    print("子线程%s结束..."%(threading.current_thread().__name__))
if __name__ == '__main__':
    print("主线程%s启动..."%(threading.current_thread().__name__))
    # 创建子线程
    t = threading.Thread(target = run,args = (1,))
    t.start()
    t.join()
    print("主线程%s结束..."%(threading.current_thread().__name__))

多线程共享资源

import threading

num = 0
var = 0
def run(n):
    global num
    for i in range(1000000):
        num += n
        num -= n
def run1(n):
    global var
    for i in range(100):
        var += n
        var -= n

if __name__ == '__main__':
    t1 = threading.Thread(target=run,args=(6,))
    t2 = threading.Thread(target=run,args=(9,))
    t3 = threading.Thread(target=run,args=(5,))
    t3.start()
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    t3.join()
    print("num = %s"%(num))

互斥锁

import threading

创建锁对象

lock = threading.Lock()
num = 0

def run(n):
    global num
    for i in range(1000000):
        # 加锁  为了确保下面代码只能由一个线程从头到尾的执行
        # 会阻止多线程的并发执行,所以效率会大大降低
        """
        lock.acquire()
        try:
            num = num - n
            num = num + n
        finally:
            # 解锁
            lock.release()
        """
        with lock:
            num = num + n
            num = num - n

if __name__ == '__main__':
    t1 = threading.Thread(target=run,args=(6,))
    t2 = threading.Thread(target=run,args=(9,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("num = %s"%(num))