python multiprocessing多进程变量共享与加锁的实现

发布时间:2026/10/1 10:22:53
python multiprocessing多进程变量共享与加锁的实现 多进程变量共享与加锁的实现更新时间是2019年10月02日10:00:11, 作者是京酱玫瑰。这篇文章的核心内容是介绍如何实现多进程中的变量共享以及相关的加锁机制。文章内部提供了示例代码, 并且对这些示例代码的解释是非常细致的。这种详细程度的讲解, 对于大家在实际学习与工作当中具有重要的参考价值。因此需要各位关注的伙伴们接下来可以跟随小编的引导来共同参与学习, 并且进一步加深理解吧。多进程和多线程这部分内容, 是很多人会重点去了解的。这是因为在很多工作任务当中, 如果各项任务彼此之间并没有前后相互依赖的固定关系, 那么它们具体怎么安排顺序, 其实并不是非常关键的一个问题。如果我们非得采用顺序依次进行的方式来执行, 那就肯定会造成毫无意义的等待时间, 导致中央处理器和内存这两样东西白白被浪费掉, 这完全是我们不愿意看到的那种情况。为了解决这个问题, 我们可以采用多线程或者是多进程的方法。关于多线程的内容, 我们在后来的章节里再进行讲解。可是, 这两种方式之间是有着根本性的不同之处的。从内存这一个角度去考虑的话, 我们已经知道, 一个进程在执行它自身任务的过程中, 是拥有一个完全独立的内存空间的。然而, 多个线程在一起协作工作时, 它们是在共享同一个块儿内存的。这就是在多进程和多线程这两个概念里面, 存在的一个非常明显的、重大的区别所在。[]在多进程的运行环境里, 鉴于每一个进程各自拥有相互独立的内存空间, 彼此之间是处于隔离状态的, 因此大家没法通过那种直接把变量读出来的方式去实现共享操作, 面对这种情形, 就可以利用库里面所提供的那个叫做Value的对象,来帮助大家在那些各自封闭隔离的进程中顺畅地完成变量共享的任务。在下面的位置, 我们可以找到一个关于多线程程序设计的实例。假设有用来记录程序经过的总循环次数的东西, 每调用一次count函数之后就会增加20。在主程序中用循环开10个进程分别调用count函数。那么理想状态下, 在十个进程中共享的值到程序结束后应该是200。from multiprocessing import Process, Valueimport timedef count(v):for i in range(20):time.sleep(0.01)v.value 1def main():value Value(i,0)processes [Process(targetcount, args(value,)) for i in range(10)]for p in processes:p.start()for p in processes:p.join()print(value.value)if __name__ __main__:for i in range(10):main()当咱们把这个示例程序跑起来的话, 大伙儿都会去问一问, 最后能够拿到什么样的一个最终产出呢。188180168186183179186181166186我是在主程序里, 对这个程序运行了整整十次的操作, 最终得到的结果是处于160到180之间的这个范围, 总而言之的话, 是根本就没有一次的数值能够达到200的这种状态, 这具体会是什么导致这个问题的原因呢。相信好多个人差不多全都明白事情的关键点是个什么样了。之所以会这样, 原因就在于在库结构里面存放的Value它是很精细、很碎的那些级别的。这个Value里头包含了某种特定类型的对象内容。并且它又拥有了一个叫做value的属性, 就是拿这个属性来标志说明内存当中真实存在的那个具体对象的状况。因为这种构造方式的存在, 所以能够去担保、能够实现, 在任何给定的时间点上, 绝对只允许有一个单独的线程或者进程, 去对这个value值执行读取操作或者是写入操作。要是从表面现象上去看一看, 会觉得这整个环节并没有什么问题所在。但是, 在第一个程序把那个数值加载进去的时候, 它没办法去拦住第二个程序也去加载那个已经过时的旧数值, 这两个程序呀, 都会把这个数拷贝到自己各自分开的私人地方, 然后进行各种处理操作, 最后再给写回到那个大家都能用的共享区域里去。那么在这种情况下, 究竟可能会引出什么样的问题出来呢?最终的共享数值仅仅捕捉到了一次增量操作, 而没有捕捉到两次所谓的增量操作。通过使用Lock这种方式, 我们在需要让不同的进程去共同访问和操作某些变量的时候, 就会给这些变量加上锁。其实, 针对前面所提及的那个问题, 是完全可以使用一个相当简便的操作来进行处理的, 那就是去调用开发库里面所提供的那些关于Lock也就是锁的功能模块, 通过这种手段就能够确保在任何特定的时间点之内, 都只允许唯一一个进程来对这个共享的数据变量进行访问的操作行为的发生, 下面是经过了修改和完善之后的具体代码实现情况:from multiprocessing import Process, Value, Lockfrom time import sleepdef count(x,lock):for i in range(20):sleep(0.01)with lock:x.value 1def main():counter Value(i,0)lock Lock()processes [Process(targetcount,args(counter,lock)) for i in range(10)]for p in processes:p.start()for p in processes:p.join()print(counter.value)if __name__ __main__:for i in range(10):main()经过这种情况处理后, 最后得出的那个数值, 就永远是两百这个固定的结果, 不会再有任何变动了。一些补充1. 调用() 函数实际上, Value这个包里面是包含有锁这种概念的存在的。如果大家去调用相对应的函数话, 那就能够自动实现对共享变量添加锁的操作的。在大家看来这种方式其实是属于比较被倡导的一种做法来的。之所以这么讲是因为这样做使得大家就不需要同时去调用两个不同包的麻烦了。下面便是对此进行的相应修改内容展示:from multiprocessing import Process, Valuefrom time import sleepdef count(x):for i in range(20):global counter # 声明全局变量sleep(0.01)with counter.get_lock(): # 直接调用get_lock()函数获取锁x.value 1def main():processes [Process(targetcount, args(counter,)) for i in range(10)]for p in processes:p.start()for p in processes:p.join()print(counter.value)if __name__ __main__:counter Value(i, 0) # 需要把全局变量移到主程序main()这个程序把意思说得更清楚了, 而且到最后得出的那个数, 也就是结果, 还是等于200。2. 你在使用这个东西。在这个包里面, 刚才被调用的那个值对象和那个锁对象, 还可以被一个点符号统一替换。以上就是整篇文章所包含的全部内容了, 希望这些内容能够对你自身的学业产生一定的帮助, 同时呢也期盼着各位读者朋友们在未来的日子里对脚本之家这个平台给予更多且更为强大的支持与援助。