首页 > 编程语言 >python基础 - 多线程技术

python基础 - 多线程技术

时间:2024-06-23 21:33:47浏览次数:3  
标签:python t2 基础 t1 threading 线程 time print 多线程

基础概念

import time
def test(something):
print(f"我开始>>> {something}")
time.sleep(2)
print(f"我结束>>> {something}")

"""
场景:
1- io密集型--阻塞
sleep requests socket
"""
import threading
"""
threading.Thread(target=,args=)
target= 你这个带定义的线程要做的事情是什么 一般是一个函数或者方法 只能传递函数名
args= 这个函数或者方法需要传入的参数 是一个元组类型
"""
if name == 'main':
startTime = time.time()
#1- 创建线程
t1 = threading.Thread(target=test,args=("上课",))
t2 = threading.Thread(target=test, args=("喝水",))

#2- 启动线程
t1.start()
t2.start()

#主线程执行的时候,并没有去等待子线程t1  t2执行完成!
#希望,主线程退出前,检查下子线程是否运行完,子线程运行完,主线程再退出!

t1.join()
t2.join()

endTime = time.time()
print(f"耗时>>>{endTime-startTime} s")

计算密集型

def test():
num = 0
for one in range(10000000):
num += 1#num = num+1

import time
import threading
if name == 'main':
startTime = time.time()
test()# 0.36s
test()
endTime = time.time()
print(f"耗时-常规>>>{endTime - startTime} s")

startTime = time.time()
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)

#2- 启动线程
t1.start()
t2.start()

t1.join()
t2.join()
endTime = time.time()
print(f"耗时-多线程>>>{endTime - startTime} s")

守护线程

import threading
import time
def test(something):
print(f"我开始>>> {something}")
time.sleep(3)
print(f"我结束>>> {something}")

if name == 'main':
startTime = time.time()
#1- 创建线程
t1 = threading.Thread(target=test,args=("上课",))
t2 = threading.Thread(target=test, args=("喝水",))

# t1.setDaemon(True)#守护线程,主线程想要结束,可以直接自己退出,子线程不在运行!!
# t2.setDaemon(True)

#2- 启动线程
t1.start()
t2.start()

# t1.join()
# t2.join()

for one in range(2):
    print("主线程在运行!>>> ",one)
    time.sleep(1)


endTime = time.time()
print(f"耗时>>>{endTime-startTime} s")

"""
使用场景:
1- 如果只有t1.start(),没有 t1.join() 和 t1.setDaemon(True)
效果: 所有线程全部运行完成,这样会出现,主线程结束后,子线程继续运行,直到结束!
2- 如果只有t1.start(),+t1.join() ,没有t1.setDaemon(True)
效果:主线程结束前会等待所有子线程运行完成,再结束!----阻塞
3- 如果有t1.setDaemon(True),t1.start(),没有t1.join() ----守护线程
效果: 主线程完成,所有子线程都中断
"""

死锁

import threading
import time

lockA = threading.Lock() # 面试官的锁
lockB = threading.Lock() # 小明的锁

面试官

def foo1():
lockA.acquire() # 上锁
print("请解释什么是死锁")
time.sleep(1)

lockB.acquire()  # 上锁
print("发 offer")
time.sleep(1)

lockA.release()  # 释放锁
lockB.release()  # 释放锁

小明

def foo2():
lockB.acquire() # 上锁
print("请给我 offer")
time.sleep(1)

lockA.acquire()  # 上锁
print("解释了什么是死锁")
time.sleep(1)

lockA.release()  # 释放锁
lockB.release()  # 释放锁

t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)

t1.start()
t2.start()

递归锁

import threading
import time

lockR = threading.RLock() # 递归锁
"""
递归锁内部维护着一把锁和一个计数器
每次上锁,计数器加一
每次解锁,计数器减一
计数器可以大于零也可以等于零,但不能小于零
"""

面试官

def foo1():
lockR.acquire() # 上锁
print("请解释什么是死锁")
time.sleep(1)

lockR.acquire()  # 上锁
print("发 offer")
time.sleep(1)

lockR.release()  # 释放锁
lockR.release()  # 释放锁

小明

def foo2():
lockR.acquire() # 上锁
print("请给我 offer")
time.sleep(1)

lockR.acquire()  # 上锁
print("解释了什么是死锁")
time.sleep(1)

lockR.release()  # 释放锁
lockR.release()  # 释放锁

t1 = threading.Thread(target=foo1)
t2 = threading.Thread(target=foo2)

t1.start()
t2.start()

协程

import time
import gevent# pip install gevent -i https://douban.xxxxx
from gevent import monkey
monkey.patch_all()
def f(num):
for i in range(0,2):
print(f"f{num}-正在运行>>> ",i)
time.sleep(2)

if name == 'main':
startTime = time.time()#开始计时
g1 = gevent.spawn(f,1)#创建协程
g2 = gevent.spawn(f,2)#创建协程
gevent.joinall([g1,g2])

endTime = time.time()
print(f"扫描过程,耗时>>> {endTime-startTime}s")

举例 - 银行业务

"""
原本卡里 1000RMB
1- 进账 +500
2- 支出 -200

"""
import time
import threading
lock = threading.Lock()
balance = 1000# 全余额
def test(num):
global balance# 使用全局变量
lock.acquire()#上锁
#使用自己一个变量存放这个余额
userBalance = balance
#进出帐操作
userBalance = userBalance + num
time.sleep(2) # 模拟处理时间
balance = userBalance

#释放锁
lock.release()

if name == 'main':
#1-进账 500RMB
t1 = threading.Thread(target=test,args=(500,))
#1-支出 -200RMB
t2 = threading.Thread(target=test,args=(-200,))

#开启
t1.start()
t2.start()

#阻塞主线程运行!
t1.join()
t2.join()
print("卡里余额>>> ",balance)

标签:python,t2,基础,t1,threading,线程,time,print,多线程
From: https://www.cnblogs.com/running-snail-12345/p/18263941

相关文章

  • 深入理解栈:计算机科学中的基础数据结构
    1.栈的概念及结构栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(LastInFirstOut)的原则。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做......
  • python基础 - socket编程基础
    一对一---服务端importsocketip_port=('127.0.0.1',9999)1-创建socket对象---socket也叫套接字sk=socket.socket()2-绑定ip端口sk.bind(ip_port)3-开启监听sk.listen()print('---socket服务器已经启动完成---')4-阻塞等待客户端来链接可以返回连接对象......
  • SQL-Python
    师从黑马程序员数据库介绍数据库就是存储数据的库数据组织:库->表->数据数据库和SQL的关系MySQL的基础命令 SQL基础SQL语言的分类SQL的语法特征DDL-库管理showDATABASES;usesys;SELECTdatabase();CREATEDATABASEtestCHARSETutf-8;SHOWDATAB......
  • 基于 Python-Tkinter 的古诗文垂直搜索引擎(全网首份 + 包复现)
    目录一、前言二、实现效果参考文献注:①整个项目可作为本科阶段计算机NLP方向的课程设计,建议收藏。一、前言  中国古典诗词具有独特的艺术表现形式,在人们的日常生活中架起了情感共鸣的桥梁、充当了教育和启蒙的工具,其中很多古诗词蕴含着民族正气和家国情......
  • [absl_py][python]absl_py所有whl文件下载地址汇总
    absl_py是Google开发并维护的一个Python软件包,它是C++Abseil库的Python版本。该库旨在提供一系列高质量的、跨平台的实用工具,帮助开发者构建大规模软件项目。以下是关于absl_py的详细介绍:功能概述:字符串处理:absl_py提供了一组实用的字符串操作函数,包括字符串拼接、分割、......
  • python连接mysql、sqlserver、oracle、postgresql数据库进行封装
    python连接mysql、sqlserver、oracle、postgresql数据库进行封装python连接mysql、sqlserver、oracle、postgresql数据库进行封装详解一、引言二、python连接MySQL数据库进行封装三、python连接SQLServer数据库进行封装四、Python连接Oracle数据库进行封装五、Python连......
  • IA的统计学基础:深入解析与实践应用
    IA的统计学基础:深入解析与实践应用在数据泛滥的信息化时代,统计学作为解读数据语言的关键工具,对于任何希望从数据中提取价值的专业人士来说都是必修课。本文将从统计学的基本概念入手,深入探讨其技术细节,并展示如何将这些技术应用于实际问题解决中。统计学的定义与重要性统......
  • Python自动化神器:如何用PyAutoGUI模拟滚轮动一次
    哈喽,大家好,我是木头左!一、PyAutoGUI简介PyAutoGUI是一个纯Python的GUI自动化工具,其目的是可以用程序控制鼠标和键盘操作。它主要在三个方面发挥作用:1)对屏幕上的图像进行识别;2)控制鼠标和键盘的操作;3)具有强大的截图功能。二、安装PyAutoGUI使用PyAutoGUI之前,需要先进行安装。......
  • 【python】python海底捞门店营业数据分析与可视化(数据集+源码+论文)【独一无二】
    ......
  • Python基础之面向对象
    目录1面向对象1.1类方法1.1.1普通方法1.1.1.1实例调用1.1.1.2类调用1.1.2类方法1.1.3类静态方法1.2继承1.2.1单继承1.2.2多继承1.3方法重写1.4类私有属性方法和专有方法1.4.1类的私有属性1.4.2类的私有方法1.4.3类专有方法1面向对象Python从设计之初就已经是一......