python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(2)

简介: python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(2)

5、线程之间共享全局变量

# TODO 线程之间共享全局变量
import threading
import time
my_list=[]
#写入数据
def write_data():
    for i in range(5):
        my_list.append(i)
        time.sleep(0.1)
    print("write_data",my_list)
# 读取数据
def read_data():
    print("read_data",my_list)
if __name__ == '__main__':
    #  创建写入数据线程
    write_dataThred=threading.Thread(target=write_data)
    # 创建读取数据线程
    read_dataThred=threading.Thread(target=read_data)
    #开启进程
    write_dataThred.start()
    # 主线程等待写入线程执行完成以后代码再继续往下执行
    write_dataThred.join()# 等待子线程执行之后再执行下一次代码,不加这行你会发现read_data  读不到数据
    print("开始读取数据")

结果:image.pngread_data 哪去了??????image.png从上图可以发现只要重新启动read_dataThred线程就可以了你难道认为这样就可以了吗,太天真了。-_-下面再引入一个例子。

# TODO 线程之间共享全局变量出现问题     问题:线程不一致,交替拿变量      解决方法     保持线程同步,同一时刻只能有一个线程去操作全局变量    两种方式   线程等待  +  互斥所
import threading
#  创建函数,实现循环100万次,每次全局变量加一
g_num=0
# 每次全局变量加一
def sun_num():
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num",g_num)
# 每次全局变量加一
def sun_num2():
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num2", g_num)
if __name__ == '__main__':
    sun_numThred=threading.Thread(target=sun_num)
    sun_num2Thred=threading.Thread(target=sun_num2)
    #开启线程
    sun_numThred.start()
    sun_num2Thred.start()

结果:image.pngimage.png结果是出结果了,但是你们细看一下代码,你们不感觉这个答案有问题吗?有没有这样一个疑问,for循环,遍历共享变量,最后应该是1000000和2000000啊,怎么打印出来的是1000000和1456202,而且细心的你还会发现每次的大男孩不一样。想要解决问题应该怎么办呢?问题总结:线程不一致,交替拿变量 解决方法 保持线程同步,同一时刻只能有一个线程去操作全局变量 两种方式 线程等待 + 互斥所线程等待:join出场ticle/details/123494962

# TODO 线程之间共享全局变量出现问题     问题:线程不一致,交替拿变量      解决方法     保持线程同步,同一时刻只能有一个线程去操作全局变量    两种方式   线程等待  +  互斥所
import threading
#  创建函数,实现循环100万次,每次全局变量加一
g_num=0
# 每次全局变量加一
def sun_num():
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num",g_num)
# 每次全局变量加一
def sun_num2():
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num2", g_num)
if __name__ == '__main__':
    sun_numThred=threading.Thread(target=sun_num)
    sun_num2Thred=threading.Thread(target=sun_num2)
    #开启线程
    sun_numThred.start()
    # # TODO 方法一
    sun_numThred.join()
    sun_num2Thred.start()

结果:image.png线程等待,当前线程等待其他线程执行某些操作,典型场景就是生产者消费者模式,在任务条件不满足时,等待其他线程的操作从而使得条件满足。等到其他线程完成操作释放后再分配线程。当前线程获得资源继续执行操作。

6、互斥锁

****互斥锁 Lock():在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

互斥锁三步骤 ~~~ 创建一把锁==》上锁==》释放锁 三步走

#  TODO   互斥锁  Lock()
import threading
# # TODO 创建一把锁==》上锁==》释放锁   三步走
# mutext=threading.Lock()
# mutext.acquire()
# mutext.release()
#定义全局变量
g_num=0
# 创建一把锁
mutext=threading.Lock()
# 每次全局变量加一
def sun_num():
    # TODO   上锁
    mutext.acquire()
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num",g_num)
    # TODO  释放锁
    mutext.release()
# 每次全局变量加一
def sun_num2():
    # TODO 上锁
    mutext.acquire()
    for i in range(1000000):
        global g_num
        g_num+=1
    print("sun_num2", g_num)
if __name__ == '__main__':
    sun_numThred=threading.Thread(target=sun_num)
    sun_num2Thred=threading.Thread(target=sun_num2)
    #开启线程
    sun_numThred.start()
    sun_num2Thred.start()

结果:image.png是不是非常神奇。主义事项:一、互斥锁就三步骤 1、创建一把锁 2、上锁 3、释放锁 。二、保证共享数据操作的完整性三、等当前上锁线程执行完成,释放锁后其他线程才能申请资源

7、死锁

死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去

# TODO  死锁
import threading
import time
# 创建互斥锁
lock=threading.Lock()
def get_value(index):
    #上锁
    lock.acquire()
    print(threading.current_thread())
    my_list=[3,4,7,2]
    # 根据下标释放取值
    if index>=len(my_list):
        print("下标越界:",index)
        # TODO  当下标越界了释放锁,让后面线程继续取值
        # lock.release()
        return
    value=my_list[index]
    print(value)
    time.sleep(0.2)
    #释放锁
    # lock.release()
if __name__ == '__main__':
    #模拟大量线程取值
    for i in range(30):
        sub_thred=threading.Thread(target=get_value,args=(i,))
        sub_thred.start()

结果:image.png注释掉释放锁的操作,线程刚执行就卡住了,产生了死锁。

打开释放所操作

# TODO  死锁
import threading
import time
# 创建互斥锁
lock=threading.Lock()
def get_value(index):
    #上锁
    lock.acquire()
    print(threading.current_thread())
    my_list=[3,4,7,2]
    # 根据下标释放取值
    if index>=len(my_list):
        print("下标越界:",index)
        # TODO  当下标越界了释放锁,让后面线程继续取值
        lock.release()
        return
    value=my_list[index]
    print(value)
    time.sleep(0.2)
    #释放锁
    lock.release()
if __name__ == '__main__':
    #模拟大量线程取值
    for i in range(30):
        sub_thred=threading.Thread(target=get_value,args=(i,))
        sub_thred.start()

结果:image.png1、因为我们是用方式传参,循环30次,索引0~29。

2、我们会发现我们在判断越界后,因为释放锁所以仍会输出。

3、加入互斥锁解除了死锁危机。

目录
相关文章
|
5天前
|
机器学习/深度学习 算法 异构计算
m基于FPGA的多通道FIR滤波器verilog实现,包含testbench测试文件
本文介绍了使用VIVADO 2019.2仿真的多通道FIR滤波器设计。展示了系统RTL结构图,并简述了FIR滤波器的基本理论,包括单通道和多通道的概念、常见结构及设计方法,如窗函数法、频率采样法、优化算法和机器学习方法。此外,还提供了Verilog核心程序代码,用于实现4通道滤波器模块,包含时钟、复位信号及输入输出接口的定义。
20 7
|
5天前
|
API 数据库 数据安全/隐私保护
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】Django REST framework (DRF) 是用于构建Web API的强力工具,尤其适合Django应用。本文深入讨论DRF面试常见问题,包括视图、序列化、路由、权限控制、分页过滤排序及错误处理。同时,强调了易错点如序列化器验证、权限认证配置、API版本管理、性能优化和响应格式统一,并提供实战代码示例。了解这些知识点有助于在Python面试中展现优秀的Web服务开发能力。
22 1
|
2天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
28 1
|
2天前
|
Java
面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
6 1
|
4天前
|
前端开发 测试技术 C++
Python自动化测试面试:unittest、pytest与Selenium详解
【4月更文挑战第19天】本文聚焦Python自动化测试面试,重点讨论unittest、pytest和Selenium三大框架。unittest涉及断言、TestSuite和覆盖率报告;易错点包括测试代码冗余和异常处理。pytest涵盖fixtures、参数化测试和插件系统,要注意避免过度依赖unittest特性。Selenium的核心是WebDriver操作、等待策略和测试报告生成,强调智能等待和元素定位策略。掌握这些关键点将有助于提升面试表现。
18 0
|
4天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
13 0
|
5天前
|
SQL 中间件 API
Flask框架在Python面试中的应用与实战
【4月更文挑战第18天】**Flask是Python的轻量级Web框架,以其简洁API和强大扩展性受欢迎。本文深入探讨了面试中关于Flask的常见问题,包括路由、Jinja2模板、数据库操作、中间件和错误处理。同时,提到了易错点,如路由冲突、模板安全、SQL注入,以及请求上下文管理。通过实例代码展示了如何创建和管理数据库、使用表单以及处理请求。掌握这些知识将有助于在面试中展现Flask技能。**
12 1
Flask框架在Python面试中的应用与实战
|
6天前
|
数据可视化 Python
Python模型评估与选择:面试必备知识点
【4月更文挑战第17天】本文深入探讨了Python模型评估与选择在面试中的关键点,包括性能度量、过拟合与欠拟合识别、模型比较与选择、模型融合和偏差-方差权衡。强调了避免混淆评估指标、忽视模型验证和盲目追求高复杂度模型的常见错误,并提供相关代码示例,如交叉验证、网格搜索和超参数调优。通过理解这些概念和技巧,可在面试中展示出色的数据科学能力。
31 12
|
6天前
|
机器学习/深度学习 搜索推荐 Python
Python特征工程面试:从理论到实践
【4月更文挑战第17天】本文探讨了Python在数据科学面试中的特征工程,涵盖基础概念如特征选择和提取,实战技能如缺失值和异常值处理,以及特定场景应用。强调避免过度依赖单一方法,忽视数据分布和相关性,以及保持特征工程的可解释性。提供代码示例展示了处理缺失值、标准化、特征选择和异常值检测的基本操作。建议结合业务理解,灵活运用多种方法并注重模型解释性。
21 9
|
6天前
|
数据采集 机器学习/深度学习 数据挖掘
Python数据清洗与预处理面试题解析
【4月更文挑战第17天】本文介绍了Python数据清洗与预处理在面试中的常见问题,包括Pandas基础操作、异常值处理和特征工程。通过示例代码展示了数据读取、筛选、合并、分组统计、离群点检测、缺失值和重复值处理、特征缩放、编码、转换和降维。强调了易错点,如忽视数据质量检查、盲目处理数据、数据隐私保护、过度简化特征关系和忽视模型输入要求。掌握这些技能和策略将有助于在面试中脱颖而出。
23 8

热门文章

最新文章