注意:我理解的任务:是能够实现某种功能的代码。可以是一个程序,一个进程,一个函数,一行代码,是一个宽泛的概念。
单任务没后续 做完拉倒(实现了一个功能) 多任务是系列任务 做起来ONE BY ONE(实现了多个功能) 就这意思
一、什么是多任务?
多个任务在同一个操作系统上同时运行,这种机制就是多任务。
二、实现多任务的机制
串行:多个任务依次执行,前面的任务不完成后面的任务不能开启。
并行:多个任务同时执行,他们之间的执行互不影响。并行系统需要有多机支持,多个CPU或者内核或者一个服务器集群。一旦有新的任务产生,这个任务会被分配到一个空闲的处理机上执行。
并发:多个任务以时间片为单位根据特定处理机分配算法来交替执行;例如:一个操作系统中同时打开微信,浏览器,pycharm,并发执行是让微信执行1ns让出cpu,然后浏览器再执行1ns然后让出cpu,然后pycharm再执行1ns让出cpu,然后替换微信,依次轮询下去,在宏观上来看1ns这个时间片人类无法感知。
三、多任务实现技术
1、进程与多进程
什么是进程?
一个程序运行起来以后,操作系统首先为他创建一个或者多个进程;一个进程包含进程id、机器源码,资源(内存资源和I/O资源(例如访问网络,访问内存),以及处理机资源)。
对于一些比较耗时的操作或者复杂的操作,如果都在同一个进程中执行,这些任务把当前进程阻塞(假死),我们可以在主进程中开启一个子进程,让子进程和主进程并发(围观上面是交替进行,宏观上是同时进行)执行。一般异步并发实现
代码演示
两个任务都在同一个进程中,当前任务不执行完,后面的任务不能开启,这就就是同步
from multiprocessing import Process #导入进程对象
from time import sleep
import os
def func(string):
while True:
print(string)
print(os.getpid())
sleep(1)
if __name__ == '__main__':
#创建func任务函数
func("hello")
while True:
print("我是主进程!我的进程ID为:",os.getpid())
sleep(1)
hello
8448
hello
8448
hello
8448
func中的任务放在子进程中执行,p进程开启以后,两个进程(子进程主进程),子进程就会和主进程并发异步执行
from multiprocessing import Process
# 导入进程对象
from time import sleep
import os
def func(string):
while True:
print(string)
print("当前子进程的ID为:",os.getpid())
sleep(1)
if __name__ == '__main__':
# 创建了一个进程,绑定了函数func为它的任务函数
p = Process(target=func,args=("我是子进程!",))
# 开启进程p 就会和主进程并发异步执行
p.start()
while True:
print("我是主进程!我的进程ID为:",os.getpid())
sleep(1)
我是主进程!我的进程ID是: 13528
我是子进程!
15184
我是主进程!我的进程ID是: 13528
我是子进程!
15184
2、线程与多线程
现在在进行程序设计的时候大多采用多线程,进程是操作系统分配资源的基本单位,进程之间资源是相互隔离的(两个进程的资源不共享),进程管理要依赖于操作系统,进程的切换需要不断的分配与回收资源。由于以上的操作多进程机制处理多任务的时候非常麻烦,所以采用多线程来处理;线程是进程的执行子单位,一个进程可以包含若干个线程。
如果我们进行程序设计时候采用线程机制,程序运行起来以后,操作系统会给程序创建一个进程,给这个进程分配资源(内存和IO),在进程中创建一个主线程,和若干个子线程(也有可能不创建子线程),让这些线程和其他线程或者其他进程去并发的执行。
(1)创建线程
import threading
def thead():
name = threading.current_thread().name
print(name)
if __name__ == '__main__':
thead()
MainThread
(2)守护线程
守护线程的依赖于主线程,主线程存在它才有可能存在,主线程死掉守护线程也会死掉
import threading
from time import sleep
import _thread # 用于以守护的方式给主线程开启一个子线程
# 定义一个函数,用于绑定子线程的任务
def func(string):
name = threading.current_thread().name
for i in range(1, 9):
print("当前线程%s执行了第%d次"%(name, i), string)
sleep(2)
def thead1(name):
# 给当前主线程开启一个守护子线程
_thread.start_new_thread(func, ('biubiubiu',))
for i in range(1, 9):
print("当前线程%s执行了第%d次"%(name, i))
sleep(1)
if __name__ == '__main__':
thead1("-thead1主线程-")
当前线程-thead1主线程-执行了第1次
当前线程Dummy-1执行了第1次 biubiubiu
当前线程-thead1主线程-执行了第2次
当前线程-thead1主线程-执行了第3次
当前线程Dummy-1执行了第2次 biubiubiu
当前线程-thead1主线程-执行了第4次
当前线程-thead1主线程-执行了第5次
当前线程Dummy-1执行了第3次 biubiubiu
当前线程-thead1主线程-执行了第6次
当前线程Dummy-1执行了第4次 biubiubiu
当前线程-thead1主线程-执行了第7次
当前线程-thead1主线程-执行了第8次
当前线程Dummy-1执行了第5次 biubiubiu
(3)非守护线程
一旦开启,子线程和主线程没有任何关系,只是并发执行,主线程死掉和子线程无关
import threading
from time import sleep
import _thread
def func(string):
name = threading.current_thread().name
for i in range(1, 9):
print("子线程%s执行了第%d次"%(name, i), string)
sleep(2)
def thead2(name):
# 以非守护的方式创建一个线程
thead = threading.Thread(target=func, args=('biubiubiu',))
# 开启线程
thead.start()
main_thead = threading.current_thread().name
for i in range(1, 9):
print("%s-%s执行了%d次循环"%(main_thead, name, i))
sleep(1)
if __name__ == '__main__':
thead2("thend2")
子线程Thread-1执行了第1次 biubiubiu
MainThread-thend2执行了1次循环
MainThread-thend2执行了2次循环
MainThread-thend2执行了3次循环
子线程Thread-1执行了第2次 biubiubiu
MainThread-thend2执行了4次循环
MainThread-thend2执行了5次循环
子线程Thread-1执行了第3次 biubiubiu
MainThread-thend2执行了6次循环
MainThread-thend2执行了7次循环
子线程Thread-1执行了第4次 biubiubiu
MainThread-thend2执行了8次循环
子线程Thread-1执行了第5次 biubiubiu
子线程Thread-1执行了第6次 biubiubiu
子线程Thread-1执行了第7次 biubiubiu
子线程Thread-1执行了第8次 biubiubiu
Thread-1
(4)自定义线程
重写了基类中的run()方法
import threading
from time import sleep
class MyThread(threading.Thread):
def __init__(self,name):
super().__init__()
self.name = name
# 重写Thread的run方法,来重新定义线程的功能
def run(self):
for i in range(1, 9):
print("%s执行了第%d次循环" % (self.name, i))
sleep(2)
def thread3():
# 创建自定义的线程对象
t = MyThread(name="自定义线程")
t.start()
for i in range(1, 9):
print("主线程%s执行了第%d次循环" % (threading.current_thread().name, i))
sleep(1)
if __name__ == '__main__':
thread3()
自定义线程执行了第1次循环
主线程MainThread执行了第1次循环
主线程MainThread执行了第2次循环
主线程MainThread执行了第3次循环
自定义线程执行了第2次循环
主线程MainThread执行了第4次循环
自定义线程执行了第3次循环
主线程MainThread执行了第5次循环
主线程MainThread执行了第6次循环
自定义线程执行了第4次循环
主线程MainThread执行了第7次循环
主线程MainThread执行了第8次循环
自定义线程执行了第5次循环
自定义线程执行了第6次循环
自定义线程执行了第7次循环
自定义线程执行了第8次循环