Python 基础之-进程线程
Posted cyfiy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 基础之-进程线程相关的知识,希望对你有一定的参考价值。
进程与线程
什么是进程
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。
在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。这是这样的设计,大大提高了CPU的利用率。进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
有了进程为什么还要线程?
进程有很多优点,它提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率。很多人就不理解了,既然进程这么优秀,为什么还要线程呢?其实,仔细观察就会发现进程还是有很多缺陷的,主要体现在两点上:
-
进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
-
进程在执行的过程中如果阻塞,例如等待输入,整个进程就会挂起,即使进程中有些工作不依赖于输入的数据,也将无法执行。
例如,我们在使用qq聊天, qq做为一个独立进程如果同一时间只能干一件事,那他如何实现在同一时刻 即能监听键盘输入、又能监听其它人给你发的消息、同时还能把别人发的消息显示在屏幕上呢?你会说,操作系统不是有分时么?但我的亲,分时是指在不同进程间的分时呀, 即操作系统处理一会你的qq任务,又切换到word文档任务上了,每个cpu时间片分给你的qq程序时,你的qq还是只能同时干一件事呀。
再直白一点, 一个操作系统就像是一个工厂,工厂里面有很多个生产车间,不同的车间生产不同的产品,每个车间就相当于一个进程,且你的工厂又穷,供电不足,同一时间只能给一个车间供电,为了能让所有车间都能同时生产,你的工厂的电工只能给不同的车间分时供电,但是轮到你的qq车间时,发现只有一个干活的工人,结果生产效率极低,为了解决这个问题,应该怎么办呢?。。。。没错,你肯定想到了,就是多加几个工人,让几个人工人并行工作,这每个工人,就是线程!
什么是线程
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务
进程和线程的区别
import threading import time def sayhi(num): # 定义每个线程要运行的函数 print("running on number:%s" % num) time.sleep(3) if __name__ == ‘__main__‘: t1 = threading.Thread(target=sayhi, args=(1,)) # 生成一个线程实例 t2 = threading.Thread(target=sayhi, args=(2,)) # 生成另一个线程实例 t1.start() # 启动线程 t2.start() # 启动另一个线程 print(t1.getName()) # 获取线程名 print(t2.getName())
继承式调用
import threading import time class MyThread(threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num def run(self): # 定义每个线程要运行的函数 print("running on number:%s" % self.num) time.sleep(3) if __name__ == ‘__main__‘: t1 = MyThread(1) t2 = MyThread(2) t1.start() t2.start() print(t1.getName()) # 获取线程名 print(t2.getName())
下面是一个对多线程的一个处理方法:(需要理解):
import threading import time def run(n): print("task: ",n) time.sleep(2) print("task done: ",n) start_time = time.time() for i in range(10): t = threading.Thread(target=run,args=(i,)) t.start() print("cost: ",time.time() - start_time)
运行结果如下所示:
是因为这个程序本身就是一个主线程,主线程又起了子线程,这时子线程和主线程已经没关系了,相当于子线程和主线程是并行的。这就解释了为什么我的主线程启动了子线程之后,没有等子线程执行完毕,主线程就继续往下走了。
但是现在有个问题,我们需要计算所有线程的执行时间,并且让所有线程运行之后再运行主程序
这里就需要用到线程里的一个方法join()意思其实就是等待的意思代码如下:
import threading import time def run(n): print("task: ",n) time.sleep(2) print("task done: ",n) start_time = time.time() t_obj = [] #存线程实例 for i in range(10): t = threading.Thread(target=run,args=(i,)) t.start() t_obj.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里 for i in t_obj: #循环线程实例列表,等待所有线程执行完毕 i.join() print("all thread is done") print("cost: ",time.time() - start_time)
没有加join的时候,主线程不会等子线程执行完毕再往下走,主线程和子线程的执行完全是并行的,没有依赖关系,你执行,我也执行。但是,你会发现,最终退出的时候,主线程依然会等待所有的子线程执行完毕才退出程序。虽然不等你执行完毕才往下走,但是在程序退出之前,会默认还有一个join
但加了join的时候,主线程依赖子线程执行完毕之后, 再往下走,这是JOIN 的作用。
关于守护线程
如果将线程设置为守护线程,则主程序不会管线程是否执行完,只有主程序执行完毕之后,就会结束
代码例子如下:
import threading import time def run(n): print("task: ",n) time.sleep(2) print("task done: ",n) start_time = time.time() for i in range(10): t = threading.Thread(target=run,args=(i,)) t.setDaemon(True) #把当前线程设置为守护线程 t.start() print("all thread is done",threading.current_thread(),threading.active_count()) print("cost: ",time.time() - start_time)
以上是关于Python 基础之-进程线程的主要内容,如果未能解决你的问题,请参考以下文章