一.操作系统
计算机是由一个或者多个处理器cpu,内存条,磁盘,键盘,鼠标,显示器,以及克重其他输入输出设备组成的机器,操作系统也是一个软件。
操作系统的定义:操作系统是一个用来协调,管理和控制计算机硬件和软件资源的系统程序,
他位于硬件和应用程序之间,起承上启下的作用。我们写好的程序只需要给操作系统即可,操作系统会给我们的程序分配内存等等一些操作
二.多任务
1.多任务就是同一时刻多个任务同时执行,对于电脑来说,及时同时运行多个应用程序,例如QQ,微信,浏览器等等。
2.单核,双核CPU介绍:
单核CPU指得是CPU中有一个核心(新形象理解CPU是人的头,核心是头里面的包含的大脑),用来处理程序。
双核/四核CPU就是2个或者4个核心,(1个脑袋中涨了2个大脑或者4个大脑),相当于有2个单核CPU或者是4个CPU
3.查看CPU:
电脑–》属性–》设备管理器–》处理器,有4个便是一个CPU中有4个核心
4。在python中实现多任务有3种方式,进程,线程,协程。
三.进程
1.什么是进程
运行起来的应用程序被称之为进程,也就是说程序不运行的时候我们称之为程序,当程序运行起来他就是一个进程。通俗的理解就是不运行的时候我们称之为程序,当程序运行起来他他就是一个进程,程序和进程的对应关系是程序只有一个,但是进程可以有很多个。(进程是系统进行资源分配和调度的基本单位。)
2.创建多进程
(1).不使用多进程实现控制台先打印唱歌然后在打印跳舞。
import time
def sing():
'''唱歌三秒钟'''
for i in range(3):
print('---正在唱歌---')
time.sleep(1)
def dance():
#跳舞三秒钟
for i in range(3):
print('---正在跳舞---')
time.sleep(1)
if __name__=='__main__':
sing()
dance()
打印结果:
---正在唱歌---
---正在唱歌---
---正在唱歌---
---正在跳舞---
---正在跳舞---
---正在跳舞---
(2).使用进程让唱歌和跳舞一起执行
import time
import multiprocessing
def sing ():
'''唱歌三秒'''
for i in range(3):
print('---正在唱歌--')
time.sleep(1)
def dance():
#跳舞三秒
for i in range(3):
print('---正在跳舞---')
time.sleep(1)
def main():
p1=multiprocessing.Process(target=sing)#创建 进程 p1 ,执行sing函数
p2=multiprocessing.Process(target=dance)#创建进程p2,执行dance函数
p1.start()#开始执行进程p1
p2.start()#开始执行进程p2
#开启了2个字进程p1 和 p2
if __name__=='__main__':
main()
打印结果:
---正在唱歌--
---正在跳舞---
---正在唱歌--
---正在跳舞---
---正在唱歌--
---正在跳舞---
程序理解:
主进程从main()开始执行,执行main函数体,当执行到p1,start()的时,创建一个子进程,
p1的子进程中的代码和主进程相同,只是程序执行的开始是sing函数体。主进程执行到p2.start()时,
同样复制一份主进程代码从danc函数体开始执行。
3.进程的状态
在程序运行的过程中,由于被操作系统的调度的算法控制,程序会进入几个状态,就绪,运行和堵塞。
(1)。就绪状态
当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态被称为就绪状态。
(2)执行/运行(running)状态当进程已获得处理机,其程序正在处理机上执行,此时的进程状态被称为执行状态
(3)堵塞(Blocked)状态正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于堵塞状态,
引起进程堵塞的事物可有多种,例如,等待i/o完成,申请缓冲区不能满足,等待信件(信号)等。
四。进程之间的通讯
Queue队列。队列是一种先进先出的储存数据结构,俩个进程通讯,就是一个字进程往queue中写内容,另一个进程从queue
中取出数据,就实现了进程间的通讯。
(1)queue队列
创建queue队列对象
参数:maxsize是队列中允许最大的项数,如果省略此参数,则无大小限制,
返回值q 是队列对象
import multiprocessing
q = multiprocessing.Queue(3) #表示只能存放3个数据
# 2.put()方法,向队列中存放数据
q.put('hello')
q.put('你好')
# 3.qsize()#获取队列中数据数量
print('有多少数据--》',q.qsize())
# 4.full()#判断队列中是否存放满了
print(q.full())
#5.get()方法,获取数据
print(q.get())
print(q.get())
小练习:
import multiprocessing##
def download_data(q):
#模拟从网上下载数据
data=['zs','ls','ww']
for i in data:
q.put(i)
print('从网上下载完了数据。。。')
def processing_data(q):
#处理数据
for i in range(q.qsize()):
print(q.get())
print('处理完了数据')
def main ():
q=multiprocessing.Queue()##创建队列
p1=multiprocessing.Process(target=download_data,args=(q,))##创建进程 process--处理
p2=multiprocessing.Process(target=processing_data,args=(q,))
p1.start()
p2.start()
if __name__=='__main__':
main()
四.进程池
我们可以使用multiprocessing模块提供的Pool类 ,可以达到进程重复利用
创建进程池对象的时候可以指定一个最大进程数,当有新的请求提交到进程池中,
如果池中的进程数还没有满,那么就会创建一个新的进程用来执行该请求,但是如果
池中的进程数满了,该请求就会等待,直到进程池中的进程有结束的了,才会使用这个结束的进程来
执行新的任务。
join 主进程等待所有的子进程执行完毕,必须在close close 等待所有的进程结束后再关闭线程池
五.线程
1.线程概念
由于进程是资源拥有者,创建,撤销与切换存在较大的内存开销,因此需要
引入轻型进程即线程
进程是资源分配的最小单位 线程是CPU调度的最小单位(程序真正执行的时候调用的是线程), 每一个进程中至少有一个线程
使用 threading 模块创建线程
导入threading模块
import time
import threading
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():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
print(threading.current_thread())#返回一个当前线程的对象
if __name__ == '__main__':
main()
print('程序结束了')
执行顺序:
首先程序运行时,程序从上往下走,遇到main()函数,然后开始执行,执行main()
函数的函数体时,又创建了俩个线程我们称之为子线程,程序运行时的线程我们称之为 主线程,然后子线程根据target=xxx,开始执行指定函数
(等子线程结束后主线程结束,程序结束了)
传递参数:
给函数传递函数,使用线程的关键字args=()进行传递参数
import time
import threading
def sing(num):
for i in range(num):
print('..正在唱歌。。',i)
time.sleep(1)
def dance(num):
for i in range(num):
print('正在跳舞。。',i)
time.sleep(1)
def main(): #给num传递参数,使用元组
t1 = threading.Thread(target=sing,args=(3,))#创建t1线程 执行sing函数
t2 = threading.Thread(target=dance,args=(3,))
t1.start()#开启t1子线程
t2.start()
if __name__ == '__main__':
main()
print('程序结束了')
.setDaemon()方法
import time
import threading
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():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.setDaemon(True) # 将t1 t2 子线程设为守护线程
t2.setDaemon(True)
t1.start()
t2.start()
if __name__ == '__main__':
main()
print('程序结束了')
实例方法:
getName() :获取线程的名称
setName():设置线程的名称
isAlive():判断当前线程的名称存活状态
import time
import threading
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():
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
#给线程设置名称
t1.setDaemon('张飞')
t2.setDaemon('关羽')
#获取线程的名称
print(t1.getName())#Thread-1
print(t2.getName())#Thread-2
if __name__ == '__main__':
main()
print('程序结束了')
.threading模块提供的方法
threading.currentThread():返回当前的线程变量
threading .enumerate ():返回一个包含正在运行的线程list。正在运行指线程启动后,
结束前,不包括启动前和终止后的线程。
threading.activeCount():
返回正在运行的线程数量,与len(threading,enumerate())有相同的结果。
import time
import threading
def sing(num):
for i in range(num):
print('。。。正在唱歌。。')
time.sleep(1)
def dance(num):
for i in range(num):
print('....正在跳舞。。。')
time.sleep(1)
print('t2--->',threading.current_thread())
def main():
t1=threading.Thread(target=sing,args=(3,))
t2=threading.Thread(target=dance,args=(3,))
t1.start()
t2.start()
print(threading.enumerate())
print(threading.active_count())
if __name__=='__main__':
main()
使用继承方式开启线程
定义一个类继承threading.Thread类
复写父类的run()方法
import threading
import time
#继承 threaing 。Thread 类
class MYThread(threading.Thread):
def __init__(self,num):
super().__init__()#调用父类的init方法
self.num=num
-
复写父类的run()方法
def run(self): for i in range(3): print('1--->>',i) time.sleep(1) if __name__=='__main__': my_thread=MYThread(3) #创建对象 my_thread.start() #开启子进程
线程之间共享全局变量
import threading
g_num=10
def test1():
global g_num #global
g_num+=1
print('test1--->',g_num)
def test2():
print('test2--->',g_num)
def main():
t1=threading.Thread(target=test1())
t2=threading.Thread(target=test2())
t1.start()
t2.start()
if __name__=='__main__':
main()