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月前
|
人工智能 安全 调度
Python并发编程之线程同步详解
并发编程在Python中至关重要,线程同步确保多线程程序正确运行。本文详解线程同步机制,包括互斥锁、信号量、事件、条件变量和队列,探讨全局解释器锁(GIL)的影响及解决线程同步问题的最佳实践,如避免全局变量、使用线程安全数据结构、精细化锁的使用等。通过示例代码帮助开发者理解并提升多线程程序的性能与可靠性。
200 0
|
3月前
|
缓存 监控 算法
唯品会item_search - 按关键字搜索 VIP 商品接口深度分析及 Python 实现
唯品会item_search接口支持通过关键词、分类、价格等条件检索商品,广泛应用于电商数据分析、竞品监控与市场调研。结合Python可实现搜索、分析、可视化及数据导出,助力精准决策。
|
2月前
|
Java 调度 数据库
Python threading模块:多线程编程的实战指南
本文深入讲解Python多线程编程,涵盖threading模块的核心用法:线程创建、生命周期、同步机制(锁、信号量、条件变量)、线程通信(队列)、守护线程与线程池应用。结合实战案例,如多线程下载器,帮助开发者提升程序并发性能,适用于I/O密集型任务处理。
290 0
|
3月前
|
监控 算法 数据安全/隐私保护
唯品会 item_get - 获得 VIP 商品详情接口深度分析及 Python 实现
唯品会item_get接口通过商品ID获取商品详情,支持价格、库存、促销等数据抓取,适用于电商分析、竞品监控与价格追踪,结合Python实现可高效完成数据获取、分析与可视化,助力精准营销决策。
|
4月前
|
数据采集 消息中间件 并行计算
Python多线程与多进程性能对比:从原理到实战的深度解析
在Python编程中,多线程与多进程是提升并发性能的关键手段。本文通过实验数据、代码示例和通俗比喻,深入解析两者在不同任务类型下的性能表现,帮助开发者科学选择并发策略,优化程序效率。
310 1
|
3月前
|
缓存 监控 数据挖掘
唯品会item_get - 获得vip商品详情深度分析及 Python 实现
唯品会 item_get 接口用于获取商品详情,包括基础信息、价格、库存、规格、促销、店铺等数据,适用于电商比价、竞品分析、数据分析等场景。接口需通过 appkey + access_token 认证,支持字段筛选,调用时需注意频率限制与数据合规使用。
|
5月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
5月前
|
数据采集 存储 Java
多线程Python爬虫:加速大规模学术文献采集
多线程Python爬虫:加速大规模学术文献采集
|
11月前
|
数据可视化 前端开发 测试技术
接口测试新选择:Postman替代方案全解析
在软件开发中,接口测试工具至关重要。Postman长期占据主导地位,但随着国产工具的崛起,越来越多开发者转向更适合中国市场的替代方案——Apifox。它不仅支持中英文切换、完全免费不限人数,还具备强大的可视化操作、自动生成文档和API调试功能,极大简化了开发流程。
|
6月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
1028 23

推荐镜像

更多