python中一个变量是如何穿梭于多线程与多进程?


python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
不定期分享一些工作学习中遇到的问题与解决方法,欢迎关注,如果有问题请在下方留言
之前在写多线程与多进程的时候,因为一般情况下都是各自完成各自的任务,各个子线程或者各个子进程之前并没有太多的联系,如果需要通信的话我会使用队列或者数据库来完成,但是最近我在写一些多线程与多进程的代码时,发现如果它们需要用到共享变量的话,需要有一些注意的地方
多线程之间的共享数据标准数据类型在线程间共享
看以下代码
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
这里我创建一个全局的int变量d,它的值是5,当我在5个线程中调用test函数时,将d作为参数传进去,那么这5个线程所拥有的是同一个d吗?我在test函数中通过id(data) 来打印一下它们的ID,得到了如下的结果
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
从结果中可以看到,在5个子线程中,data的id都是1763791776,说明在主线程中创建了变量d,在子线程中是可以共享的,在子线程中对共享元素的改变是会影响到其它线程的,所以如果要对共享变量进行修改时,也就是线程不安全的,需要加锁 。
自定义类型对象在线程间共享
如果我们要自定义一个类呢,将一个对象作为变量在子线程中传递呢?会是什么效果呢?
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
这里我定义一个简单的类,在主线程初始化了一个该类型的对象d,然后将它作为参数传给子线程,主线程和子线程分别打印了这个对象的id,我们来看一下结果
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
我们看到,在主线程和子线程中,这个对象的id是一样的,说明它们用的是同一个对象 。
无论是标准数据类型还是复杂的自定义数据类型,它们在多线程之间是共享同一个的,但是在多进程中是这样的吗?
多进程之间的共享数据标准数据类型在进程间共享
还是上面的代码,我们先来看一下int类型的变量在子进程间的共享
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
得到的结果是
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
可以看到它们的id是一样的,说明用的是同一个变量,但是当我尝试把d由int变为了string时,发现它们又不一样了……
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
于是我又尝试了list、Tuple、dict,结果它们都是不一样的,我又回过头来试着在多线程中使用列表元组和字典,结果在多线程里它们的id还是一样的 。
这里有一个有趣的问题,如果是int类型,当值小于等于256时,它们在多进程间的id是相同的,如果大于256,则它们的id就会不同了,这个我没有查看原因 。
自定义类型对象在进程间共享
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
得到的结果是
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
可以看到它们的id是不同的,也就是不同的对象 。
在多进程间如何共享数据
我们看到,数据在多进程间是不共享的(小于256的int类型除外),但是我们又想在主进程和子进程间共享一个数据对象时该如何操作呢?
在看这个问题之前,我们先将之前的多线程代码做下修改
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
我们这个代码的目的是这样,使用自定义的Data类型对象,当经过5个子线程操作以后,每个子线程对其data值进行加1操作,最后在主线程打印对象的data值 。
该输出结果如下
python中一个变量是如何穿梭于多线程与多进程?

文章插图
 
可以看到在主线程最后打印出来了5,符合我们的预期,但是如果放到多进程中呢?因为多进程下,每个子进程所持有的对象是不同的,所以每个子进程操作的是各自的Data对象,对于主进程的Data对象应该是没有影响的,我们来看下它的结果
python中一个变量是如何穿梭于多线程与多进程?

文章插图


推荐阅读