对操作系统部分只做简单阐述,主要涉及每个概念在代码中的体现,想要研究具体理论的同学,建议去学学【操作系统】这个学科
这部分只写出进程的相关内容,想要了解线程,协程的同学,请看:
线程:https://blog.csdn.net/g_optimistic/article/details/86598296
协程:https://blog.csdn.net/g_optimistic/article/details/86593625
目录
(3)进程之间的通讯:通过队列Queue,一个子进程往Queue中写数据,一个子进程从Queue中取数据
一、操作系统 Operating System
操作系统是一个用来协调,管理,控制计算机硬件和软件资源的系统程序,它位于硬件和应用程序之间,起承上启下的作用
二、多任务
1.多任务就是用一时刻多个任务同时执行
对于电脑来说,多任务就是同事运行多个应用程序
2.电脑实现多任务的原理
CPU在多个应用程序之间高速切换的结果
3.单核CPU与多核CPU
单核CPU
多核CPU
3.查看CPU
电脑-->属性-->设备管理器-->处理器
4.在python中数显多任务的三种方式
进程,线程,协程
三、进程
1.基础知识:
(1)进程和程序的区别:
进程 | 运行起来的应用程序 |
程序 | 没有运行起来的应用程序 |
程序只有一个,进程可以有多个
比如说:一台电脑上可以运行好几个qq
(2)进程的状态:
(3)在自己的电脑中查看进程
ctrl+Alt+Delete--->启动任务管理器----->进程
服务也是一个进程,后台进程
(4)重点:
进程是系统进行资源分配和调度的最小单位 |
线程是处理机分配和调度的最小单位 |
(5)使用进程实现多任务的缺点:
耗费的资源比较大,因为一个进程就需要一份系统资源
进程可以理解为复制了一份程序,加载到内存上
2.进程创建多任务
(1)不使用多任务
# 不使用多任务
import time
def sing():
for i in range(3):
print('正在唱歌...', i)
time.sleep(1)
def dance():
for i in range(3):
print('正在跳舞...', i)
time.sleep(1)
def main():
sing()
dance()
if __name__ == '__main__': # 程序的入口
main()
print('程序结束了...')
# 正在唱歌... 0
# 正在唱歌... 1
# 正在唱歌... 2
# 正在跳舞... 0
# 正在跳舞... 1
# 正在跳舞... 2
# 程序结束了...
(2)使用多任务
import time
import multiprocessing # 导入模块
def sing():
for i in range(3):
print('正在唱歌...', i)
time.sleep(1)
def dance():
for i in range(3):
print('正在跳舞...', i)
time.sleep(1)
def main():
# 创建两个进程
# target:指向执行的对象
p1 = multiprocessing.Process(target=sing) # 类名() 创建了一个对象
p2 = multiprocessing.Process(target=dance)
p1.start() # 启动进程
p2.start() # 启动进程
if __name__ == '__main__': # 程序的入口
main()
print('程序结束了...')
# 程序结束了...
# 正在唱歌... 0
# 正在跳舞... 0
# 正在唱歌... 1
# 正在跳舞... 1
# 正在唱歌... 2
# 正在跳舞... 2
程序的理解:
主进程从main()开始执行,子进程从target指向的对象开始执行
target | 指向执行的对象 |
arge | 参数,保存在元组中 |
三个进程执行的顺序是随机的,哪个先抢到CPU就先执行谁
这个程序有三个进程:一个主进程,两个子进程
主进程执行的快,但要等子进程都执行完后,主进程才会销毁
3.进程之间的通讯
(1)两个进程同时运行,谁的cpu快,就先运行谁
创建进程的时候就会重新开辟一块新的内存,自己在自己的内存上运行
import time
import multiprocessing
g_num = 10
def test1():
global g_num # 全局变量g_num=10
g_num += 1
print('test1--->', g_num) # 11
def test2():
print('test2--->', g_num) # 10
def main():
p1 = multiprocessing.Process(target=test1)
p2 = multiprocessing.Process(target=test2)
p1.start()
p2.start()
if __name__ == '__main__':
main()
# test1---> 11
# test2---> 10
(2)队列:
1)..队列是一种数据结构,先进先出(FIFO):first in first out
2)..方法:
put() | 往队列里面放数据 |
put_nowait() | 往队列里面放数据,当队列满的时候,再往进放,不会一直等待,会报错 |
get() | 从队列里面取数据 |
get_nowait() | 从队列里面取数据,当队列为空的时候,再从队列里面取数据的时候,不会一直等待,会报错 |
qsize() | 返回队列的长度 |
empty() | 判断队列是否为空 |
full() | 判断队列是否满 |
put()
put_nowait()
get() get_nowait()
同put()的效果一样
import multiprocessing
q = multiprocessing.Queue(3) # 创建一个长度为3的队列
q.put('哈哈哈...')
q.put(123)
q.put([1, 2, 3])
# q.put('xxx')
# 此时队列已经满了,再放数据会一直等待,直到有数据被使用
# q.put_nowait(1) # 报错
print(q.qsize()) # 3
print(q.empty()) # False
print(q.full()) # True
print(q.get())
print(q.get())
print(q.get())
# print(q.get())#此时,队列已空,再要从队列里面取数据,就会一直等待,直到队列里面有数据
# print(q.get_nowait()) # 报错 queue.Empty
print(q.qsize()) # 0
print(q.empty()) # True
print(q.full()) # False
(3)进程之间的通讯:通过队列Queue,一个子进程往Queue中写数据,一个子进程从Queue中取数据
进程之间的通讯(传递参数)
# 先把数据下载下来,再对这些数据进行处理
from multiprocessing import Process, Queue
def download_num(q): # 下载数据
lst = ['a', 'b', 'c']
for i in lst:
q.put(i)
print('下载完了数据...')
def process_num(q): # 处理数据
for i in range(q.qsize()):
print(q.get())
print('处理完了数据...')
def main():
q = Queue()
p1 = Process(target=download_num, args=(q,))
p2 = Process(target=process_num, args=(q,))
p1.start()
p2.start()
if __name__ == '__main__':
main()
# 下载完了数据...
# a
# b
# c
# 处理完了数据...
4.进程池
- 当需要创建的进程的数量不多的时候,用multiprocessing模块的Process创建进程
- 当需要创建的进程的数量很多的时候,用multiprocessing模块的Pool创建指定个数个子进程的进程池
- 创建进程池对象时,可以指定一个最大进程数,当有新的请求提交到进程中,如果进程池中的进程还没有满,就会创建一个新的进程来执行该请求,如果进程池满了,该请求就会等待,直到进程池中有进程结束了,才会使用这个结束的进程来执行新的任务
import time
from multiprocessing import Process, Queue, Pool
def foo(i):
print('i的值是:', i)
time.sleep(1)
print('end...')
if __name__ == '__main__':
pool = Pool(3)
for i in range(3):
pool.apply_async(func=foo, args=(i,))
pool.close()
pool.join()
print('---->>')
# i的值是: 0
# i的值是: 1
# i的值是: 2
# end...
# end...
# end...
# ---->>