认识进程和线程
什么是进程
1.进程是执行中的程序
2.拥有独立的地址空间、内存、数据栈等
3.操作系统管理进程
4.派生(fork或apswn)新进程
5.进程间通信基于IPC方式共享信息
什么是线程
1.同进程下执行,并共享相同的上下文
2.线程间的信息共享和通信更加容易
3.多线程并发执行
4.需要同步原语
并发和并行的区别
1.并发:多线程并发执行 同一个时刻只有一个线程执行 进行线程的轮询 同步原语:解释器主循环中,使用全局解释器锁GIL, 保证主循环同一时刻 只有一个控制线程在执行
2.并行:多进程并行执行 同一个时刻存在多个进程的执行
python与线程
并发原理
1.py中会开启一个解释器的进程,使用GIl来保证进程内单个时刻单个线程的执行
2.gil的原理:
- 设置gil
- 切换近一个线程去运行
- 执行下面操作
-
- 指定数量的字节码指令
-
- 线程主动让出控制权
- 把线程设置回睡眠的状态(切换出线程)
- 解锁Gil
- 重复上面的步骤
两种线程管理
- _thread: 提供了基本的线程和锁
- threading:提供了更高级别、功能更全面的线程管理
-
- 支持同步机制和守护线程
Python守护线程简述
thread模块不支持守护线程的概念,当主线程退出时,所有的子线程都将终止,不管它们是否仍在工作,如果你不希望发生这种行为,就要引入守护线程的概念。
threading模块支持守护线程,其工作方式是:守护线程一般是一个等待客户端请求服务的服务器。如果没有客户端请求,守护线程就是空闲的,如果把一个线程设置为守护线程,就表示这个线程是不重要的,进程退出时就不需要等待这个线程执行完成。
如果主线程准备退出时,不需要等待某些子线程执行完成,就可以为这些子线程设置守护线程标记。该标记为真时,表示该线程是不重要的,或者说该线程只是用来等待客户端请求而不做任何其它事情。
要将一个线程设置为守护线程,需要在启动线程之前执行如下赋值语句:thread.daemon=True。同样,要检查线程的守护状态,也只需要检查这个值即可。一个新的子线程会继承父线程的守护标记。整个Python程序(可以解读为:主线程)将在所有非守护线程退出之后才退出,换句话说,就是没有存活的非守护线程时。
需求:一个进程内有n个loop方法,怎么保证并发执行
//代码块
loops = [2, 4] # 睡眠时间
def loop(nloop, nsec):
logging.info("start loop" + str(nloop) + " at " + time.ctime())
time.sleep(nsec)
logging.info("end loop" + str(nloop) + " at " + time.ctime())
def main():
logging.info("start all at " + time.ctime())
thread = []
nloops = range(len(loops)) # 线程得数量[0,2]
for i in nloops:
print(i)
t = threading.Thread(target=loop, args=(i, loops[i])) # target表示调用的方法(loop),arg表示方法参数,t表示一个执行现成的对象
thread.append(t)#线程对象存储到列表里
for i in nloops:
thread[i].start()#开始执行线程
for i in nloops:
thread[i].join()#知道保证线程并发执行,即前面线程没执行完 后面线程将会一直阻塞
logging.info("end all at " + time.ctime())
if __name__ == '__main__':
main()