Python基础-进程和线程
多任务介绍
1.现实中多任务
吃着饭看电影
2.计算机中的多任务
计算机中多任务处理是指:操作系统同一时段内进行多项任务的处理.
多任务是指用户在同一时间段内运行多个应用程秀,每个运用程序都可以被称为一个任务
现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行多任务。由于CPU执行代码都是顺序执行的,那么,单核CPU是怎么执行多任务的呢?
答案就是操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去。表面上看,每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像所有任务都在同时执行一样。
真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数量远远多于CPU的核心数量,所以,操作系统也会自动把很多任务轮流调度到每个核心上执行。
并发与并行
- 并发处理(concurrency Processing):指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机(CPU)上运行,但任一个时刻点上只有一个程序在处理机(CPU)上运行
- 并行处理(Parallel Processing):是计算机系统中能同时执行两个或更多个处理的一种计算方法。并行处理可同时工作于同一程序的不同方面。并行处理的主要目的是节省大型和复杂问题的解决时间。
并发的关键是你有处理多个任务的能力,不一定要同时。并行的关键是你有同时处理多个任务的能力。所以说,并行是并发的子集
[外链图片转存失败(img-Oaw8dKf2-1565178293865)(C:\Users\Lenovo\Desktop\Python\图片\并行和并发.png)]
进程
一个程序的执行实例被称之为进程,每个进程都能提供程序执行所需的所有资源,因此进程本质上就是资源的集合.
进程包括:
- 虚拟地址空间
- 可执行代码
- 操作系统接口
- 安全的上下文(记录启动该进程的用户,权限等等)
- 唯一的进程ID,环境变量
- 优先级类
- 最小和最大的工作空间(内存空间)
- 至少一个线程
进程的创建:fork()
python的os模块封装了常见的系统调用函数,其中就包括了fork(),可以让我们在程序中轻松创建子进程
import os
pid=os.fork()
if pid==0:
print('zhengjiang University.')
else:
print('city college.')
在Unix/Linux中,提供了fork()系统函数
普通的函数调用时调用一次返回一次,而fork调用一次返回两次,因为操作系统会自动把当前的进程(父进程)复制一份(子进程),然后分别在父进程和子进程返回.fork()子进程永远返回0,而父进程返回子进程的ID
一个父进程可以fork出很多子进程,父进程可以记下每个子进程的ID二子进程只需调用getppid()
- getpid()返回当前进程标识
- getppid()返回父进程标识
demo:
import os
pid=os.fork()
if pid < 0:
print('fork 调用失败')
elif pid==0:
print('我是子进程:\t%s,我的父进程是:\t %s'%(os.getpid(),os.getppid()))
else:
print('我是fu进程:\t%s,我的子进程是:\t %s'%(os.getpid(),pid))
print('父子进程都可以执行这句')
'''
我是fu进程: 2639,我的子进程是: 2640
父子进程都可以执行这句
我是子进程: 2640,我的父进程是: 2639
父子进程都可以执行这句
'''
线程
线程是操作系统能够运算调度的最小单位.线程被包含进程之中,是进程中的实际运作单位.一条线程是进程中一个单一顺序的控制流,一个进程可以并发多个线程,每条线程并发执行不同的任务.
一条线程是一个execution context(执行上下文),即一个和cpu执行时所需要的一串指令.
线程的工作方式
假设你正在读一本书,没有读完,你想休息一下,但是你想在回来时恢复到当时读的具体进度。有一个方法就是记下页数、行数与字数这三个数值,这些数值就是execution context。如果你的室友在你休息的时候,使用相同的方法读这本书。你和她只需要这三个数字记下来就可以在交替的时间共同阅读这本书了。
线程的工作方式与此类似。CPU会给你一个在同一时间能够做多个运算的幻觉,实际上它在每个运算上只花了极少的时间,本质上CPU同一时刻只干了一件事。它能这样做就是因为它有每个运算的execution context。就像你能够和你朋友共享同一本书一样,多任务也能共享同一块CPU。
进程与线程的区别
- 同一进程中的线程共享同一内存空间,单相互之间是独立的.
- 同一进程中的所有数据是共享的,数据之间是独立的
- 对主线程的修改可能会影响其他线程的行为,但是父进程的修改不会影响其他子进程
- 线程是一个上下文的执行指令,而进程则是与运算相关的一簇资源。
- 同一个进程的线程之间可以直接通信,但是进程之间的交流需要借助中间代理来实现。
- 创建新的线程很容易,但是创建新的进程需要对父进程做一次复制。
- 一个线程可以操作同一进程的其他线程,但是进程只能操作其子进程。
- 线程启动速度快,进程启动速度慢(但是两者运行速度没有可比性)。
但是要注意的是:进程与线程一样有着五个阶段:创建、就绪、运行、阻塞、终止。
Python中多线程的实现
import threading
import time
def download_music():
for i in range(5):
time.sleep(1)
print('--正在下载歌曲%d--'%i)
def play_music():
for i in range(5):
time.sleep(1)
print('----正在播放歌曲%d----'%i)
def main():
#创建两个线程对象
t1=threading.Thread(target=download_music)
t2=threading.Thread(target=play_music)
t1.start()
t2.start()
if __name__=='__main__':
main()
- 可以看出使用多线程时可以节省时间
- 当我们使用sta