之前决定要把每天学习的内容记录下来,坚持了几天后发现做这事很浪费时间,于是渐渐的就落下了。
现在重新开始,并不是因为“可以帮助别人”这种高大上的理由(毕竟小白一个,如果很幸运刚好被需要,那确实是很值得的开心的事情),仅仅是因为害怕 习惯性放弃。做过的事情,有余力做完,且算得上是一件不错的事,不做下去始终是遗憾。
目录
1、多任务
好处:充分利用cpu资源,提高程序的执行效率
方式:并发 、 并行
并发:在意短时间内交替执行
并行:同时执行多个任务
实现多任务的方法:进程、线程
进程: 一个正在运行的程序或者软件 操作系统进行资源分配的基本单位。
(操作系统按按进程分配资源 有一个进程就会分配一份内存资源)
进程:并发、并行
线程: 程序进程中执行代码的分支。 线程工作需要 cpu 的调度。CPU调度的基本单位。
线程:一定是并发
关系: 一个程序运行后至少有一个进程,一个进程默认有一个线程。线程依附在进程里,没有进程就没有线程。
一个进程可以有多个线程。
1.1 进程的使用
1.1.1多进程实现多任务
# 多进程的使用
import multiprocessing
import time
def work_one():
for i in range(2):
print("执行任务一")
time.sleep(0.2)
def work_two():
print("执行任务二")
# 在主模块中创建进程
if __name__=="__main__":
# 1、创建进程对象 指定执行任务
# 格式:multiprocessing.Process(group=None[,target[,name[,args[,kwargs]]]])
# group 目前只能是 None
# target 指定要执行的任务
# name 给进程命名(默认是process_n)
sub_process_one = multiprocessing.Process(group=None,target=work_one,)
sub_process_two = multiprocessing.Process(group=None,target=work_two)
# 2、启动进程对象
sub_process_one.start()
sub_process_two.start()
"""
执行结果:
执行任务二
执行任务一
执行任务一
Process finished with exit code 0
"""
1.1.2执行带有参数的任务
Process传参方式
1.args:以元的方式传参 (only one element , )
按位传参,传参顺序和参数顺序一致。
2.kwargs:以字典的方式传参{key:value...}
字典中的key 一定要和参数保持一致。顺序可以不一致。
import multiprocessing
def test(name, age):
print(name)
for i in range(count):
if __name__ == '__main__':
# 创建子进程
# 元组如果只有一个元素,那么元素后面的逗号不能省略
# args: 表示以元组方式给执行任务传参数, 实际上是按照函数位置参数进行传参的。
sub_process = multiprocessing.Process(target=test, args=(3, "xiahua"),name="sub_process")
sub_process.start()
# kwargs: 表示以字典方式给执行任务传参数, 实际上是按照函数关键字传参的。
# sub_process = multiprocessing.Process(target=task, kwargs={"name":"xiaohua", "age":18})
# sub_process.start()
1.1.3 GET PROCESS ID
os.getpid() 当前进程编号
os.getppid() 当前进程父进程编号
在进程所执行的任务代码中获取。
获取当前代码的进程对象 multiprocessing.current_process()
所有的代码都是在进程中的线程中执行的,所以所有当前执行的代码都有自己的进程和线程。
import multiprocessing
import os
def work_one():
print("任务一")
# 获取当前代码进程对象
work_one_process = multiprocessing.current_process()
# 输出当前代码进程对象
print(work_one_process)
# 获取当前代码的进程对象的进程编号
work_one_pid = os.getpid()
# 获取当前代码进程对象的父进程编号
work_one_ppid = os.getppid()
# 打印进程编号
print("work_one_pid:",work_one_pid)
# 打印父进程编号
print("work_one_ppid:",work_one_ppid)
def work_two():
print("任务二")
# 获取执行当前代码的进程对象
work_two_process = multiprocessing.current_process()
# 打印进程对象
print("work_two_process:",work_two_process)
# 获取进程编号
work_two_pid = os.getpid()
# 打印进程编号:
print("work_two_pid:",work_two_pid)
# 获取父进程编号
work_two_ppid = os.getppid()
#打印父进程编号
print("work_two_ppid:",work_two_ppid)
if __name__=="__main__":
# 获取当前代码进程对象
main_process = multiprocessing.current_process()
print("main_process:",main_process)
# 获取当前进程的编号
main_pid = os.getpid()
print("main_pid:",main_pid)
sub_process_one = multiprocessing.Process(group=None, target = work_one, name="sub_process_one")
sub_process_two = multiprocessing.Process(group=None, target = work_two, name="sub_process_two")
print("sub_process_one:", sub_process_one)
print("sub_process_two:", sub_process_two)
sub_process_two.start()
sub_process_one.start()
"""
执行结果:
/usr/bin/python3.5 /home/python/untitled/02-获取进程编号.py
main_process: <_MainProcess(MainProcess, started)>
main_pid: 5491
sub_process_one: <Process(sub_process_one, initial)>
sub_process_two: <Process(sub_process_two, initial)>
任务二
work_two_process: <Process(sub_process_two, started)>
work_two_pid: 5494
work_two_ppid: 5491
任务一
<Process(sub_process_one, started)>
work_one_pid: 5495
work_one_ppid: 5491
Process finished with exit code 0
"""
通过进程编号可以看出子进程是由哪个父进程创建。
1.1.4. PROCESS NOTES
进程间不共享全局变量。
父进程默认需等所有子进程结束才结束。
because:进程是操作系统分配资源的基本单位。操作系统会给每一个进程分配一份内存资源。
即每个进程所占用的内存资源是相互独立的。当多个子进程操作操作一个名为XXX的全局变量时,实质操作的是自己内存的一个变量不会影响其他进程。
import multiprocessing
import time
def test(num):
"""
此函数执行完需要unm*0.2s
:param num:
"""
for i in range(num):
print("sub_process正在工作阶段%d" %i)
time.sleep(0.2)
# 创建子进程
# args:采用元组方式传参,test()执行时间大约0.6s
sub_process = multiprocessing.Process(group=None, target=test, args=(3,))
# 启动子线程
sub_process.start()
# 主线程延时0.4s
time.sleep(0.4)
print("代码执行到此处,主线程结束")
"""
执行结果:
sub_process正在工作阶段0
sub_process正在工作阶段1
代码执行到此处,主线程执结束
sub_process正在工作阶段2
Process finished with exit code 0
"""
显然:主线程结束后,并没有立即退出,而是在等待子线程执行。
若想主进程结束就退出程序:
设置守护主进程:子进程对象.daemon = True
销毁子进程:子进程对象.terminate()
mport multiprocessing
import time
def test(3):
"""
此函数执行完大约需要0.6s
:param num:
"""
for i in range(num):
print("sub_process正在工作阶段%d" %i)
time.sleep(0.2)
# 创建子进程
sub_process = multiprocessing.Process(group=None, target=test)
# 设置主线程守护,主线程退出子线程销毁,停止运行。
sub_process.daemon = True
# 启动子线程
sub_process.start()
# 主线程延时0.4s
time.sleep(0.4)
print("代码执行到此处,主线程结束")
"""
执行结果:
sub_process正在工作阶段0
sub_process正在工作阶段1
代码执行到此处,主线程执结束
Process finished with exit code 0
"""