专栏首页生信了浅谈python中的多线程和多进程(二)

浅谈python中的多线程和多进程(二)

本文继续分享一个关于python多线程和多进程区别的例子

前文《浅谈python中的多线程和多进程》中我们分享过一个例子,就是分别利用python中的多线程和多进程来解决高运算量的任务,从中看出二者的一些区别。其中一点是“多线程会共享所属进程的内存资源;而子进程会从父进程那里拷贝一份内存资源”。当时没有进一步解释,为了更直观地了解这一点,本文给出一个例子。

我们用python分别创建多线程和多进程,然后打印出其中的变量和函数的id。这里的id是指python中对象的唯一标识符,可以通过id(obj)函数获得。如果两个对象的值相等,它们不一定是同一个对象,即它们的id不一定相等;反过来说,如果“两个”对象的id一样,那么它们其实是同一回事,就是同一个对象,它们的值一定相等。

我们首先用python创建多线程并打印其中对象的id。代码如下:

from threading import Thread
import time

# all subthreads share data.
def run_subthread(thread_id):
    time.sleep(thread_id + 1)
    print("inside run_subthread: a = %d, id(a) = %d, id(run_subthread) = %d" % (a, id(a), id(run_subthread)))

a = 10
print("outside run_subthread: a = %d, id(a) = %d, id(run_subthread) = %d" % (a, id(a), id(run_subthread)))

if __name__ == "__main__":
    threads = [Thread(target=run_subthread, args=(idx, )) for idx in range(2)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print "all done"

运行结果如下:

从中可以看出,不同线程中的对象id是一样的,也就是说多线程共享了同一份对象资源。

然后我们用python创建多进程并打印其中对象的id。代码如下:

from multiprocessing import Process
import time

# each subprocess has its own copy of data.
def run_subproc(proc_id):
    time.sleep(proc_id + 1)
    print("inside run_subproc: a = %d, d(a) = %d, id(run_subproc) = %d" % (a, id(a), id(run_subproc)))

a = 10
print("outside run_subproc: a = %d, id(a) = %d, id(run_subproc) = %d" % (a, id(a), id(run_subproc)))

if __name__ == "__main__":
    proc = [Process(target=run_subproc, args=(idx, )) for idx in range(2)]
    for p in proc:
        p.start()
    for p in proc:
        p.join()
    print "all done"

运行结果如下:

从中可以看出,不同子进程中的对象id是不一样的(变量和函数的id都不一样),说明多进程中,每个子进程都拷贝了父进程的一份对象资源。

除此之外,我们还可以看到,与多线程不同的是,多进程中的每个子进程都还执行了print("outside run_subproc: a = %d, id(a) = %d, id(run_subproc) = %d" % (a, id(a), id(run_subproc)))这一句。关于这一点的机制笔者并不完全清楚,不过它提醒我们,如果我们用python的多进程,要注意一些目标函数(target)之外的语句也可能会被执行,这并不是我们所期望的。

本文分享自微信公众号 - 生信了(gh_ed36a29a9a9d),作者:hxj7

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • R语言模拟疫情传播-gganimate包

    前文《R语言模拟疫情传播-RVirusBroadcast》已经介绍了一种用R语言模拟疫情传播的方法,不过当时为了实时模拟数据(没有事先准备好的数据集可用)的动态...

    一只羊
  • R语言模拟疫情传播-RVirusBroadcast

    前几天微博的一个热搜主题是“计算机仿真程序告诉你为什么现在还没到出门的时候!!!”,该视频用模拟的疫情数据告诉大家“不要随便出门(宅在家)”对战胜疫情很重要,生...

    一只羊
  • (转载)用Annovar注释人类以外的基因组

    Annovar是一款对基因组数据进行注释的软件。所谓注释,可以这样简单理解:我们知道二代测序下机后的序列经过比对后,会得到一系列变异数据,这些变异数据只是告诉我...

    一只羊
  • Bypass 360主机卫士SQL注入防御(多姿势)

    在服务器客户端领域,曾经出现过一款 360 主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影。

    信安之路
  • 「数据库」sql刷题(No.6)

    Hello 各位 ,我是公号「八点半技术站」的创作者 - Bruce.D (姓氏:豆)。

    八点半的Bruce、D
  • Mybatis系列第7篇:各种查询详解

    Mybatis系列目标:从入门开始开始掌握一个高级开发所需要的Mybatis技能。

    路人甲Java
  • python中查看变量内存地址的方法

    本文实例讲述了python中查看变量内存地址的方法。分享给大家供大家参考。具体实现方法如下:

    py3study
  • Bypass 360主机卫士SQL注入防御(多姿势)

    在服务器客户端领域,曾经出现过一款360主机卫士,目前已停止更新和维护,官网都打不开了,但服务器中依然经常可以看到它的身影。从半年前的测试虚拟机里面,翻出了36...

    Bypass
  • 面试题|无索引如何删除亿级数据?

    存在索引的情况下就比较简单,直接利用索引进行删除,写一个for 循环语句 每次删除500行,每次判断delete 影响的行数可以累加计算删除了多少行,直到删除结...

    用户1278550
  • 面试题|无索引如何删除亿级数据?

    存在索引的情况下就比较简单,直接利用索引进行删除,写一个for 循环语句 每次删除500行,每次判断delete 影响的行数可以累加计算删除了多少行,直到删除结...

    [3306 Pai ] 社区

扫码关注云+社区

领取腾讯云代金券