用好这两个方法,解决Python中的线程同步问题

了解互斥锁和连接,实现Python中安全有效的多线程。

微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩

同步的重要性是什么?

假设有一个共享的家庭银行账户,余额为50美元,属于你和你父亲。

爸爸挣钱后把钱存进银行账户,不花钱,而你来花钱。

如果把这句话写成代码,从50美元的初始投资开始,爸爸向银行账户存入10美元,使总金额达到60美元。同时,你花了10美元,结果余额为50美元(60-10=50)。

然而,当爸爸和你同时进行交易时,会出现一个复杂的情况。

考虑到如果爸爸增加10美元,结果是50+10=60,而如果你花10美元,结果是50-10=40。就会少了10美元......

这就是所谓的“竞争条件”。

当有不良的程序设计,并且有几个进程和线程试图访问相同的资源时,就会出现“竞争条件”。

这种竞争条件是出了名的难以调试。可能有一个代码已经运行了数周而没有发生任何意外,然后在一天由于这种竞争条件而突然崩溃了。

进行编码

from threading import Thread
import timeclass JointAccount:current_balance = 50def dad(self):for i in range(1000000):self.current_balance += 10print('Dad saved!')def son(self):for i in range(1000000):self.current_balance -= 10print('Son Spent!')account = JointAccount()
Thread(target=account.dad, args=()).start()
Thread(target=account.son, args=()).start()
time.sleep(5) # 在这里,让两个线程都完成。
print(f"The current balance in the account is: {account.current_balance}")

输出是:

Dad saved!
Son Spent!
The current balance in the account is: -963810

可以看出,这里有一个错误!预测结果是60,但观察到的是-963810。如果再试一次,可以不断获得各种结果。

如何才能使这一问题得到解决?

如果要克服竞争条件,需要使用同步。

如何使用同步?

有2种同步技术。互斥锁是其中之一,另一种是利用连接。

1.互斥锁

为了理解这一点,可以想象一把锁保护一段特定的代码并且一次只允许一个线程访问它。

为了确保在任何给定时候只有一个线程可以访问银行账户,必须限制对场景中的current_balance变量的访问。

假设没有其他人锁定current_balance,爸爸将按照常规程序请求锁定它。爸爸在进行锁定调用后会收到一条信息,即他正持有该互斥锁。

在爸爸完成对current_balance的更新后,他将解锁,以便其他线程可以访问它。儿子也将遵循类似的程序。

如果一个线程已经持有一个mutex,而另一个线程请求它,请求的线程将被置入睡眠状态并一直等待,直到mutex被释放。

如果两个线程同时尝试访问,则保证只有一个线程可以访问并锁定它。

锁的实现

from threading import Thread, Lock
import timeclass JointAccount:current_balance = 50mutex = Lock()def dad(self):for i in range(1000000):self.mutex.acquire()self.current_balance += 10self.mutex.release()print('Dad saved! ')def son(self):for i in range(1000000):self.mutex.acquire()self.current_balance -= 10self.mutex.release()print('Son spend!')account = JointAccount()
Thread(target=account.dad, args=()).start()
Thread(target=account.son, args=()).start()
time.sleep(5) # 在这里,让两个线程都完成。
print("current_balance remaining is: ", account.current_balance)

输出是:

Dad saved! 
Son spend!
current_balance remaining is:  50

2.连接

什么是连接?

连接是一种使线程能够等待直到另一个线程执行完毕的方法。

实践连接

一个主线程创建一个子线程来执行任务。该子线程开始执行其任务。

在进入睡眠状态之前,主线程将调用join()函数。join()函数将保留主线程,直到子线程完成其任务并终止。

一旦子线程执行完毕,join()函数将释放,主线程将被唤醒并继续执行。

单一任务的JOIN()的实现

import time
from threading import Threaddef child():print("subThread is created!")print("subThread is doing work")time.sleep(10)print("subThread work's done")def parent():t = Thread(target=child, args=([]))t.start()print("mainThread thread put to sleep")t.join() # Parent将被封锁,直到child终止。# t.join(timeout=10)print("mainThread is awaken")

如果只是想让父母等待一段时间,就使用timeout

输出是:

subThread is created!
subThread is doing work
mainThread thread put to sleep
subThread work's done
mainThread is awaken

假设任务量很大,比如渲染图像。想尽可能迅速地完成这项任务。怎样才能做到这一点呢?为了加速渲染过程,将把图像分割成多个部分,并为每个部分分配不同的线程。将有一个主线程产生许多子线程。主线程等待所有的子线程完成渲染工作,它将与第一个子线程连接,开始渲染,接着是第二个子线程,以此类推,直到生成整个图像。为了实现这一点,将利用一个for循环。任何已经完成的线程将立即渲染。

首先,将尝试在不使用线程的情况下进行:

写一个脚本来查找一个词,然后将该词号与相应的短语相匹配。

matches = []passage1 = """This is a sample passage
with multiple lines and words.
It is meant to demonstrate how to
search for a specific word in Python."""# 循环浏览每一行和每一个词,找到特定的词
def word_search(word, passage):# 把这段话分成几行lines = passage.split("\n")for i, line in enumerate(lines):words = line.split()for j, w in enumerate(words):if w == word:matches.append(i+1)matches.append(j+1)if __name__ == '__main__':word_search('demonstrate', passage1)print("matched!")print("Sentence is :", matches[0])print("Word is :", matches[1])

现在以join()的方式重写以上代码:

from threading import Lock, Threadmutex = Lock()
matches = []passage1 = """This is a sample passage
with multiple lines and words.
It is meant to demonstrate how to
search for a specific word in Python."""# 循环浏览每一行和每一个词,找到特定的词
def word_search(word, passage):# 把这段话分成几行lines = passage.split("\n")for i, line in enumerate(lines):words = line.split()for j, w in enumerate(words):if w == word:mutex.acquire()matches.append(i+1)matches.append(j+1)mutex.release()if __name__ == '__main__':t = Thread(target=word_search, args=(['demonstrate', passage1]))t.start()t.join() # 等待它完成print("matched!")print("Sentence is :", matches[0])print("Word is :", matches[1])

总结

理解互斥锁和连接对于在Python中实现安全和有效的多线程是至关重要的。互斥锁提供了一种方法,以确保一次只有一个线程访问共享资源,防止竞争条件和其他并发性问题。连接允许一个线程等待另一个线程完成后再继续,确保在程序终止前完成所有必要的工作。通过在多线程Python程序中加入这些技术,可以提高它们的安全性、效率和可靠性,从而提高整体性能,减少错误。

推荐书单

《Python从入门到精通(第2版)》

《Python从入门到精通(第2版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。全书共分23章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库、GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架、e起去旅行网站、AI图像识别工具等内容。所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。除此之外,该书还附配了243集高清教学微视频及PPT电子教案。

《Python从入门到精通(第2版)》【摘要 书评 试读】- 京东图书京东JD.COM图书频道为您提供《Python从入门到精通(第2版)》在线选购,本书作者:明日科技,出版社:清华大学出版社。买图书,到京东。网购图书,享受最低优惠折扣!icon-default.png?t=N5K3https://item.jd.com/13284890.html

精彩回顾

《深入浅析,一步步用GPT打造你的聊天机器人》

《用好这9个技巧,让你的Python代码“飞”起来》

《领略数学之美,使用Python创建分形图案》

《使用Python进行自动化录屏》

《轻松完成异步任务,一文搞懂Python Celery》

《ChatGPT插件使用攻略,解锁互联网新体验》

微信搜索关注《Python学研大本营》,加入读者群

访问【IT今日热榜】,发现每日技术热点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/64033.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

了解Python编码风格,让你的代码更好看

和其他编程语言不同,Python有一套独特的编码风格,掌握Python的编码风格对于编写优美的代码至关重要。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 本文是一篇快速了解Python编码风格的指南,了解Python…

国家电网可视化平台完工交付给客户!

国家电网可视化平台完工交付给客户,助力电网信息化! 转载于:https://www.cnblogs.com/shuzikeji/p/7844358.html

2019年南方电网和国家电网考纲对比(通信类)

最近在准备关于国家电网和南方电网的校园招聘笔试,整理了如上内容,仅供参考,小结如下: 南方电网: 批次:南方电网校园招聘考试一般每年只有一批,比重:比较注重面试环节,面…

国家电网 计算机 《信息新技术》 整理

信息新技术概论 分布式处理基础分布式数据库(DDB,Distributed Database)︰分布式文件系统(DFS,Distributed File System)区块链(Blockchain): 物联网基础基本概念 大数据基础人工智能基础神经网络(NNsNeural Networks)机器学习 典型硬件技术基…

【NLP】千呼万唤始出来——GPT-3终于开源!

文 | 小戏编 | 小轶 GPT3终于开源!不过,不是官方开的(别打我 Eleuther AI推出的名为GPT-Neo的开源项目,于今晨4点于twitter正式宣布:已经开源了复现版GPT-3的模型参数(1.3B和2.7B级别)&#xff…

属于自己的贾维斯

属于自己的贾维斯之Python学习 人生第一次写博客,想记录下自己的学习过程,以便以后复习简单(毕竟自己的博客总想知道有没有人来看,就可以顺便过来复习了),因为用笔的记录感觉都没怎么去看,所以就想用这种方法来记录。因为本人比较懒再加上精神…

七夕送女友什么礼物有意义、送女朋友实用的七夕礼物清单

在即将到来的中国传统情人节——七夕节当中,怎样送女朋友实用又用心的礼物呢?想必有不少男生朋友们不知道怎么选择吧!要知道合适的礼物可以在改善生活质量的同时也为彼此的感情带来惊喜,今天就为大家带来送女朋友实用的5个礼物推荐…

七夕节送女朋友什么礼物、能让女生感动到哭的礼物推荐

七夕作为我国的传统情人节马上就要到来了。在这一天也是恋爱中人相互向对方表达爱意的好时机,精心为对方准备一份七夕礼物也是情理之中的事,但是咱们很多男性小伙伴在面对市面上令人眼花缭乱礼物的时候,在挑选问题上却是不知从何下手了。别担…

程序员如何哄女朋友开心的秘籍,定制给女朋友一个应用(生日礼物)

这算是我写的安卓比较完整的一个应用了吧,不过其实也还不怎么完整,还有好多功能没有加进去,但是由于昨天是女朋友的生日,所以就送给他了,这也是我学习安卓半个月来的第一个应用了“音乐播放器”! 制作&…

女朋友过生日送什么礼物好?

观察她喜欢什么 平日里陪她逛街购物时,你留意到她很喜欢一件衣服或是饰品之类的,她可能因为各种原因,没买。你记在心里面,生日前买下了,作为生日礼物送个她,她会非常的欢喜。 如果离过生日还有很长一段时间…

如何做一个网页送给女朋友做生日礼物!感动到哭!

如何做一个网页送给女朋友做生日礼物 本文里面涉及到python,HTML ,css,JavaScript的知识,是基于python的flask框架做的一个小型网站,里面可以实现跳转功能,怎么配置flask的环境变量,去官方文档看就好了&am…

情人节送女朋友什么礼物最好?五大首选礼物排行榜单!

一年一度的情人节又要到了,各位男生有没有因为不知道给女朋友们挑选什么礼物而心慌慌?情人节礼物绝对能反映出你对女朋友平时喜好的了解程度,选对了情人节礼物,可以让你们的感情更加甜蜜。今天就来说说有哪几款非常适合送女孩子的…

如何做一个网页送给女朋友做生日礼物!这应该是最好的礼物了!

如何做一个网页送给女朋友做生日礼物 本文里面涉及到python,HTML ,css,JavaScript的知识,是基于python的flask框架做的一个小型网站,里面可以实现跳转功能,怎么配置flask的环境变量,去官方文档看就好了&am…

这是我送给兄弟女朋友的六一礼物

这是我送给兄弟女朋友的六一礼物 1. 写在前面2. 前期准备2.1. 需要安装的库2.2. 安装库的命令2.3. 库的介绍 3. 代码展示4. 运行结果展示5. 总结 1. 写在前面 事情是这样的,最近不是六一儿童节嘛,好像我身边充斥着大量大龄儿童。我兄弟就是木讷&#xf…

给女友的网页小惊喜,(生日,周年,表白通用) ☞谁说程序员不懂浪漫

有女朋友的拿去给女朋友一个惊喜&#xff0c;没女朋友的拿去表白&#xff0c;或者NEW它10000000个&#xfeff;ε≡٩(๑>₃<)۶ 文章目录 前言适用范围网页展示登录界面文字界面图片界面尾部界面 获取源码 前言 前些日子是女友的一周年&#xff0c;康康想用一种特殊的方…

520送什么给男朋友最好?送男朋友礼物排行榜

520要到啦&#xff0c;还没给男朋友准备好礼物的小伙伴儿们就赶紧收藏好这份超级礼物清单吧&#xff01;就我个人而言&#xff0c;有意义的礼物无非是让他感受到你的心意&#xff0c;大多数男生一般都不太会期待女生送来多珍贵的礼物&#xff0c;相反的是&#xff0c;他们更期待…

520送男朋友什么礼物比较好、520给男朋友的实用性礼物

520节日马上来临&#xff0c;各位女生朋友有没有想好给男票准备爱的礼物呢&#xff1f;对于男生来说&#xff0c;最关注的莫过于数码产品和游戏&#xff0c;所以准备礼物的时候往这个方向靠拢准没错&#xff01;但是部分女生对于这方面可能还是小白&#xff0c;所以小编在这里也…

七夕送女朋友什么礼物比较有意义!女生都拒绝不了的礼物推荐篇

马上就是七夕啦&#xff01;是不是很多朋友们都在想着到底送什么礼物给对方才会更合适呢&#xff01;别担心&#xff0c;身为一个好物推荐博主&#xff0c;在各种节日已经来去自由&#xff0c;对于女孩子喜欢的东西&#xff0c;那当然是女孩子更懂女孩子啦&#xff01;下面就是…

python程序员怎么给女朋友准备礼物

先来展示一下效果图&#xff1a; 不知道大家给女朋友的备注是什么&#xff1f;下面看看我的备注。 这是我给女朋友的备注&#xff1a; 再来看看给女朋友一个发射爱心的图片&#xff0c;这个叫“既许一人以偏爱&#xff0c;愿尽余生之慷慨”&#xff0c; 看完了发射爱心&#x…

生日快乐送女朋友的网页生日礼物模版

生日快乐送女朋友的网页生日礼物模版 Demo: http://sylvanding.online/happy-birthday-20221120 仓库&#xff1a;https://github.com/sylvanding/happy-birthday-20221120 参考 背景 https://codepen.io/arcs/pen/XKKYZW蛋糕 https://codepen.io/fixcl/pen/AaBNZB卡片 http…