深入理解上篇之 Python的进程和线程深刻理解前一章中Python的流程和线程,
python视频教程栏目介绍进程和线程。
进程和线程都是操作系统中的基本概念。他们之间有一些优点和缺点。Python中如何使用进程和线程?
CPU
计算机的核心是CPU,承担着计算机的所有计算任务。CPU就像一个工厂,一直在运行,而操作系统管理着计算机,负责任务调度、资源分配和管理。
进程
流程是指可以在系统中独立运行的资源分配的基本单位。它由一组机器指令、数据和栈组成,是一个可以独立运行的活动实体。
打开电脑就能看到进程和线程,点开我的电脑就能看到CPU运行。
从图中可以看出,CPU总共运行190个进程和2620个线程。例如,当我们再次点击QQ并登录到另一个帐户时,将启动另一个QQ流程。
所以,如果你想在电脑上登录多个微信。找到你的微信快捷方式,右键查看属性,复制目标中的链接;新建一个记事本,随便取一个名字,双击打开,输入start ‘ ‘(注意引号是英文,前后有空格),粘贴刚刚复制的链接(即微信安装路径);然后复制整行,想开几个微信就贴几行;保存文件并将后缀改为bat。双击运行。
线程
Thread也叫轻量级进程,是操作系统可以调度操作的最小单元。它包含在流程中,是流程中的实际操作单元。
记得阮一峰的博客:假设工厂的动力有限,一次只能供给一个车间。也就是说,当一个车间启动时,其他所有车间都必须关闭。这意味着单个CPU一次只能运行一个任务。
一个流程就像一个工厂里的车间,代表着CPU可以处理的单一任务。在任何时刻,CPU总是运行一个进程,其他进程不运行。
线就像车间里的工人。一个进程可以包括多个线程,它们一起工作来完成一个任务。
总而言之:程序可以包含多个进程,多个进程并发执行,相互独立,因此,进程也是系统进行资源分配和调度基本单位。专业化来说:进程是指程序执行时的一个实例。线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程,完全由操作系统决定。
在Python中线程和进程的使用
现在我们来谈谈Python线程和进程的使用。
在Python中,线程和线程这两个标准库为线程提供支持,线程封装线程。线程模块提供线程、锁定、锁定、条件和其他组件
Thread
Python中线程和进程的使用是通过Thread类实现的。这个类在我们的_thread和threading模块中。我们通常通过线程导入。
默认情况下,只要它在解释器中,如果没有报告错误,线程是可用的。
从线程导入线程复制代码以下是线程类的常见参数描述和示例方法。
我们来看一个公文中标准多线程的例子。
导入线程
导入时间
#定义线程要运行的函数
def func(name):
#睡眠2秒观察
time.sleep(2)
打印(‘我的名字是% s \ t“% name”)
#创建第一个线程的实例。args参数是一个元组,必须用逗号分隔
t1=线程。Thread(target=func,args=(‘Runsen ‘,))
#创建第二个线程的实例
t2=线程。线程(目标=func,参数=(‘李茂’,))
t1.start()
t2.start()
#首先打印线程名称
print(t1.getName())
Print(t2.getName ()) Copy Code因为两个线程同时运行,所以打印处理的结果不会换行。
我写了下面的代码来深化线程模块的使用。
# -*-编码:utf-8 -*-#时间:2019/4/9 21:52 # author : Runsen import threading import timedef fun 1():
打印(“你好”)
time.sleep(2)
打印(“再见”)def fun2():
打印(“嗨”)
time.sleep(2)
打印(“输出”)
t1=线程。线程(目标=fun1)
t2=线程。线程(目标=fun2)
t1.start()
T2。start () # t1。join () # t2。join()打印(“主线程完成”)复制代码。以下是输出。
你好
你好
主线完成
再见
OUT复制代码由于没有先添加join()而被阻塞,t1和t2线程同时执行。由于位置关系,首先打印hello,然后打印hi。此时都是休眠2秒,但它休眠2秒,主程序还在执行,所以打印下面的打印(主线程完成),最后打印Bye和OUT。
线程间变量的共享
在多线程中,所有变量由所有线程共享。所以线程间共享数据最大的危险是多个线程同时修改一个变量,这很乱,所以我们需要互斥锁来锁数据。
代码如上图所示。上面的代码是1还是2打印的A?
答案是:2。由于全局关键字和线程之间的变量共享,in func函数是一个全局变量。因此,函数的值会发生变化。
现在,让我们稍微提高一下难度。代码如下图所示。我们来猜猜A是什么。注意:这里的join出现阻塞,还有加减运算。
相信很多人认为是0。其实这个A的价值是变化的。这次可能是0,下次可能是1,也可能是100万。例如,我可以
a是[-100000,100000]中的随机数。
为什么?这是因为他们虽然在同时运行,但是同时在修改我们的A,一塌糊涂。在In for i in range(1000000)中,A遍历了100000,incr和decr方法都加在一起了。在这10万次遍历中,不知道加多少,减多少。比如我加了100000没有减,A是1000000,但是出现这种情况的概率很低。
如果只是想要0,只需要添加一个互斥体。这样我加多少减多少,加减的次数就不叠加了。所以介绍锁的用法,具体代码如下图所示。
怎么在0点运行。因为我们锁定了这个A,它会加1,000,000次,减1,000,000次,怎么出来就是我们的0。