当前位置: 首页 > news >正文

多线程的特点与同步、互斥锁

线程之间执行是无序的
线程执行是根据cpu调度决定的

线程之间执行是无序的

# #导入线程模块
# import threading
# #导入时间模块
# import time
#Thread线程类参数
# target:执行的任务名
# args:以元组的形式给任务传参
# kwargs:以字典的形式给任务传参# def task():
#     time.sleep(1)
#     print("当前线程是:",threading.current_thread().name)    #显示当前线程对象名
# if __name__ == '__main__':
#     for i in range(5):
#         # 每循环一次就创建一个子线程
#          t = threading.Thread(target=task)
#          # 启动子线程
#          t.start()

线程之间共享资源


# li = []  #定义全局变量
# # 写入数据
# def wdata():
#     for i in range (5):
#         li. append (i)
#         time.sleep (1)
#     print('写入的数据是:',li)
# #读取数据
# def rdata():
#     print('读取的数据是:',li)
# if __name__ == '__main__':
#     #创建子线程
#     wd = threading.Thread(target=wdata)
#     rd = threading.Thread(target=rdata)
#     #开启子线程
#     wd.start()
#     wd.join()   #阻塞线程
#     rd.start()
#     rd.join()# 线程之间共享资源(全局变量)
#
# # from threading import Thread   #导入线程模块
# import threading
# import time
# li = []  #定义全局变量
# # 写入数据
# def wdata():
#     for i in range (5):
#         li. append (i)
#         time.sleep (0.2)
#     print('写入的数据是:',li)
# #读取数据
# def rdata():
#     print('读取的数据是:',li)
# if __name__ == '__main__':
#     #创建子线程
#     t1 = threading.Thread(target=wdata)
#     t2 = threading.Thread(target=rdata)
#     #开启子线程
#     t1.start()
#     #阻塞线程
#     # t1.join()   #加了join()就会等待t1任务执行结束
#     time.sleep(1)   #时间一定要匹配    time.sleep(0.8)
#     t2.start()
#     t2.join()
#

资源竞争


#导入线程模块
import threading
#导入时间模块
import time# a = 0
# b = 10000000
# def add():
#     for i in range (b):
#         global a        #Python 中的 global关键字主要用于在函数内部声明一个变量为全局变量,从而允许你在函数内部读取、修改在函数外部定义的全局变量,而不是创建一个新的局部变量
#
#         a+=1
#     print('第一次累加:',a)
#
# def add2():
#     for i in range (b):
#         global a
#         a+=1
#     print('第二次累加:',a)
#
# # add()
# # add2()
# if __name__ == '__main__':
#      a1=threading.Thread(target=add)
#      a2 = threading.Thread(target=add2)
#      a1.start()
#      a2.start()
#
# # 数大了之后计算机计算不过来就会抢资源,导致算错   资源竞争#资源竞争
#
# from threading import Thread
# # import threading
#
# a=0
# b=1000000
# #循环一次就给全局变量a+1
# def add():
#     for i in range (b):
#         global a
#         a+=1
#     print("第一次:",a)
# # add()
#
# def add2():
#     for i in range (b):
#         global a
#         a+=1
#     print("第二次:",a)
#
#
# add()     #第一次100000
# add2()    #第二次200000
#
# if __name__ == '__main__':
#     first = Thread(target=add)
#     second = Thread(target=add2)
#     first.start()
#     second.start()#资源竞争
#
# from threading import Thread
# # import threading
#
# a=0
# b=1000000
# #循环一次就给全局变量a+1
# def add():
#     for i in range (b):
#         global a
#         a+=1
#     print("第一次:",a)
# # add()
#
# def add2():
#     for i in range (b):
#         global a
#         a+=1
#     print("第二次:",a)
#
#
# add()     #第一次100000
# add2()    #第二次200000
#
# if __name__ == '__main__':
#     first = Thread(target=add)
#     second = Thread(target=add2)
#     first.start()
#     second.start()

线程同步

主线程和创建的子线程之间各自执行完自己的代码直至结束

 1.线程等待
2.互斥锁

线程等待


# #导入线程模块
# import threading
# #导入时间模块
# import time# a = 0
# b = 10000000
# def add():
#     for i in range (b):
#         global a        #Python 中的 global关键字主要用于在函数内部声明一个变量为全局变量,从而允许你在函数内部读取、修改在函数外部定义的全局变量,而不是创建一个新的局部变量
#         a+=1
#     print('第一次累加:',a)
#
# def add2():
#     for i in range (b):
#         global a
#         a+=1
#     print('第二次累加:',a)
#
# if __name__ == '__main__':
#      a1=threading.Thread(target=add)
#      a2 = threading.Thread(target=add2)
#      a1.start()
#      a1.join()   #等待a1子线程执行结束以后,代码再继续往下运行,开始执行a2子线程
#      a2.start()
#      a2.join()
#

互斥锁

概念:对共享数据进行锁定,保证多个线程访问共享数据不会出
现数据错误问题:保证同一时刻只能有一个线程去操作。
方法:
acquire():上锁
release():释放锁
注意:这两个方法必须成对出现,否则容易形成死锁。


#导入线程模块
# import threading
#导入时间模块
# import time
#导入互斥锁模块
from threading import Lock
#1.创建全局互斥锁
lock = Lock()
a = 0
b = 10000000
def add():#2.上锁lock.acquire()for i in range (b):global a        #Python 中的 global关键字主要用于在函数内部声明一个变量为全局变量,从而允许你在函数内部读取、修改在函数外部定义的全局变量,而不是创建一个新的局部变量a+=1print('第一次累加:',a)#3.释放锁lock.release()def add2():# 2.上锁lock.acquire()for i in range (b):global aa+=1print('第二次累加:',a)# 3.释放锁lock.release()if __name__ == '__main__':a1=threading.Thread(target=add)a2 = threading.Thread(target=add2)a1.start()#a1.join()   #等待a1子线程执行结束以后,代码再继续往下运行,开始执行a2子线程a2.start()#a2.join()

总结

1.互斥锁的作用:保证同一个时刻只有一个线程去操作共享数据,保证共享数据不会出现错误问题
2.上锁和释放锁必须成对出现,否则容易造成死锁现象
死锁:一直等待对方释放锁的情景就是 死锁会造成应用程序停止响应,不能再处理其他任务      3.互斥锁的缺点:会影响代码的执行效率

http://www.dtcms.com/a/389691.html

相关文章:

  • 将npm run dev 冷启动从 90s 优化到 8.5s的实践
  • 【附源码】基于SSM的小型银行贷款系统设计与实现
  • X-Forwarded-For
  • 中科大DSAI Lab团队多篇论文入选ICCV 2025,推动三维视觉与泛化感知技术突破
  • GitHub 上 Star 数量前 10 的开源项目管理工具
  • axios函数封装
  • NewSQL——核心原理与内部机制
  • 《从 0 到 1 打通网络服务任督二脉:域名、服务器与多站点配置全攻略》​
  • vue3学习日记(十七):动态路由使用解析
  • SpringBoot 启动流程
  • .NET驾驭Word之力:结构化文档元素操作
  • 解密F5负载均衡:优化网络性能的关键
  • 使用 .NET Core 6 Web API 的 RabbitMQ 消息队列
  • 时空预测论文分享:图时空注意力网络 ConvLSTM 时空演变
  • 千问大模型部署笔记
  • 网络:开源网络协议栈介绍
  • 设计模式(C++)详解—装饰器模式(3)
  • 双重锁的单例模式
  • 管理 Git 项目中子模块的 commit id 的策略
  • 跨境电商API数据采集的流程是怎样的?
  • rust编写web服务07-Redis缓存
  • 第三十三天:高精度运算
  • 写联表查询SQL时筛选条件写在where 前面和后面有啥区别
  • ARM(13) - PWM控制LCD
  • Python基础 3》流程控制语句
  • 牛客算法基础noob44——数组计数维护
  • 并发编程原理与实战(三十)原子操作进阶,原子数组与字段更新器精讲
  • 前端-详解Vue异步更新
  • 基于风格的对抗生成网络
  • 【JavaScript】SSE