1.进程、线程网络
1.1.进程
进程 : 进程就是程序在计算机中一次执行的过程。每一个进程提供执行程序所需的所有资源。(进程本质上是资源的集合)
一个进程有一个虚拟的地址空间、可执行的代码、操作系统的接口、安全的上下文(记录启动该进程的用户和权限等等)、唯一的进程ID、环境变量、优先级类、最小和最大的工作空间(内存空间),还要有至少一个线程。
每一个进程启动时都会最先产生一个线程,即主线程。然后主线程会再创建其他的子线程。
与进程相关的资源:
- 内存页(同一个进程中的所有线程共享同一个内存空间)
- 文件描述符(e.g. open sockets)
- 安全凭证(e.g.启动该进程的用户ID)
进程和程序的区别:
程序是一个静态文件的描述,不占计算机的系统资源
进程是一个动态的过程,占有cpu内存等资源,有一定的生命周期
进程和线程的区别:
- 同一个进程中的线程共享同一内存空间,但是进程之间是独立的。
- 同一个进程中的所有线程的数据是共享的(进程通讯),进程之间的数据是独立的。
- 对主线程的修改可能会影响其他线程的行为,但是父进程的修改(除了删除以外)不会影响其他子进程。
- 线程是一个上下文的执行指令,而进程则是与运算相关的一簇资源。
- 同一个进程的线程之间可以直接通信,但是进程之间的交流需要借助中间代理来实现。
- 创建新的线程很容易,但是创建新的进程需要对父进程做一次复制。
- 一个线程可以操作同一进程的其他线程,但是进程只能操作其子进程。
- 线程启动速度快,进程启动速度慢(但是两者运行速度没有可比性)。
2.线程
2.1.线程的概念
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。一个线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令。
2.2.线程的工作方式
假设你正在读一本书,没有读完,你想休息一下,但是你想在回来时恢复到当时读的具体进度。有一个方法就是记下页数、行数与字数这三个数值,这些数值就是execution context。如果你的室友在你休息的时候,使用相同的方法读这本书。你和她只需要这三个数字记下来就可以在交替的时间共同阅读这本书了。
线程的工作方式与此类似。CPU会给你一个在同一时间能够做多个运算的幻觉,实际上它在每个运算上只花了极少的时间,本质上CPU同一时刻只干了一件事。它能这样做就是因为它有每个运算的execution context。就像你能够和你朋友共享同一本书一样,多任务也能共享同一块CPU。
3.多线程
3.1.线程常用方法
3.2.线程的执行方式
3.2.1普通线程的创建
import threading import time def test(n): print('thread',n) time.sleep(3) print('over') t1 = threading.Thread(target=test,args=('tt1',)) # 启动一个线程t1,执行test函数,参数为字符串tt1 t2 = threading.Thread(target=test,args=('tt2',)) t1.start() # 使用两个线程执行这个函数,cpu在t1执行完print后,遇到sleep,就会切换到t2执行print t2.start()
3.2.2.类的形式启动线程
import threading class MyThread(threading.Thread): def __init__(self,n): super(MyThread,self).__init__()# 重构run函数必须要写 self.n = n def run1(self):# 这里必须是run函数,不能取其他名,里面写死了会调用run函数 print('run thread',self.n) t1 = MyThread('tt1') t2 = MyThread('tt2') t1.start() t2.start()