Python3并发编程-多线程threading怎么用?
同一进程的各个线程间可以共享主线程的地址空间和各种资源。
1:线程的创建
1.1:Thread类创建线程
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771
# -*- coding: utf-8 -*-
from threading import Thread
import os
import time
def func(index,dic):
print(f'线程{index};进程id={os.getpid()}')
dic['cnt'] += 1
count = 0
while True:
time.sleep(1)
if count > 2:
break
count += 1
dic['cnt'] += 1
print(f'线程{index};cnt=[{dic["cnt"]}]')
print(f'线程{index};cnt=[{dic["cnt"]}],退出')
def main():
dic = {}
dic['cnt'] = 0
t_list = []
for i in range(5):
t = Thread(target=func, args=(i, dic,)) # 线程中数据是共享的,看dic中数据的变化
# t.setDaemon(True) # 默认为False;设置为True时,主线程退出时,子线程也会退出
t.start()
# print(t.getName()) # 获取线程名称
t_list.append(t)
print(f'主线程,进程id={os.getpid()}')
for t in t_list:
t.join() # 等待线程的结束,非必须。
print(f'主线程;cnt=[{dic["cnt"]}],退出')
if __name__ == '__main__':
main()
1.2:继承Thread类的子类创建
# -*- coding: utf-8 -*-
from threading import Thread
import os
import time
class MyThread(Thread):
def __init__(self, index,dic):
super().__init__()
self.index = index
self.dic = dic
def run(self): # 调用start()函数之后会自动调用此函数
print(f'线程{self.index};进程id={os.getpid()}')
self.dic['cnt'] += 1
count = 0
while True:
time.sleep(1)
if count > 2:
break
count += 1
self.dic['cnt'] += 1
print(f'线程{self.index};cnt=[{self.dic["cnt"]}]')
print(f'线程{self.index};cnt=[{self.dic["cnt"]}],退出')
def main():
dic = {}
dic['cnt'] = 0
t_list = []
for i in range(5):
t = MyThread(i, dic)
# t.setDaemon(True) # 默认为False;设置为True时,主线程退出时,子线程也会退出
t.start()
# print(t.getName()) # 获取线程名称
t_list.append(t)
print(f'主线程,进程id={os.getpid()}')
for t in t_list:
t.join() # 等待线程的结束,非必须。
print(f'主线程;cnt=[{dic["cnt"]}],退出')
if __name__ == '__main__':
main()
2:线程的同步
同一进程下的线程资源是共享的,但是对共享数据的操作是不安全的,因此需要进行同步操作。
2.1:锁:Lock
# -*- coding: utf-8 -*-
from threading import Thread
from multiprocessing import Lock
import os
import time
def func(index,dic,lock):
print(f'线程{index};进程id={os.getpid()}')
while True:
try:
lock.acquire()
cnt = dic['cnt']
time.sleep(0.0001) # 加点延时,不然看不到效果
if cnt > 0:
dic['cnt'] -= 1
print(f'线程{index};获取到:{cnt}号票;剩下={dic["cnt"]};')
else:
lock.release()
break
lock.release()
except:
break
print(f'线程{index};cnt=[{dic["cnt"]}],退出')
def main():
lock = Lock()
dic = {}
dic['cnt'] = 20
t_list = []
for i in range(5):
t = Thread(target=func, args=(i, dic,lock,)) # 线程中数据是共享的,看dic中数据的变化
# t.setDaemon(True) # 默认为False;设置为True时,主线程退出时,子线程也会退出
t.start()
# print(t.getName()) # 获取线程名称
t_list.append(t)
print(f'主线程,进程id={os.getpid()}')
for t in t_list:
t.join() # 等待线程的结束,非必须。
print(f'主线程;cnt=[{dic["cnt"]}],退出')
if __name__ == '__main__':
main()
把锁注释掉,看运行结果:
# -*- coding: utf-8 -*-
from threading import Thread
from multiprocessing import Lock
import os
import time
def func(index,dic,lock):
print(f'线程{index};进程id={os.getpid()}')
while True:
try:
# lock.acquire()
cnt = dic['cnt']
time.sleep(0.0001) # 加点延时,不然看不到效果
if cnt > 0:
dic['cnt'] -= 1
print(f'线程{index};获取到:{cnt}号票;剩下={dic["cnt"]};')
else:
# lock.release()
break
# lock.release()
except:
break
print(f'线程{index};cnt=[{dic["cnt"]}],退出')
def main():
lock = Lock()
dic = {}
dic['cnt'] = 20
t_list = []
for i in range(5):
t = Thread(target=func, args=(i, dic,lock,)) # 线程中数据是共享的,看dic中数据的变化
# t.setDaemon(True) # 默认为False;设置为True时,主线程退出时,子线程也会退出
t.start()
# print(t.getName()) # 获取线程名称
t_list.append(t)
print(f'主线程,进程id={os.getpid()}')
for t in t_list:
t.join() # 等待线程的结束,非必须。
print(f'主线程;cnt=[{dic["cnt"]}],退出')
if __name__ == '__main__':
main()
2.2:死锁
死锁就是有多个锁,多个线程中互相等待对方的锁。
比如:
有两个锁:锁A,锁B;
有两个线程:线程A,线程B
在线程A中已获取锁A,在线程B中已获取锁B,然后在线程A中要获取锁B,而此时锁B已在线程B中被占有,线程A中只能等待;在线程B中,又要获取锁A,而锁A已在线程A中被占有,这时线程B只能等待;就这样形成了,线程A,线程B分别在等待对方释放自己所要的锁。
# -*- coding: utf-8 -*-
from threading import Thread
from multiprocessing import Lock
import os
import time
from threading import Thread,Lock
import time
def funcA(lockA,lockB):
print(" funcA:需要A锁")
lockA.acquire()
time.sleep(0.2)
print(" funcA:获得了:A锁")
print(" funcA:需要B锁")
lockB.acquire() # B锁 在funcB中被占有,而在funcB中又在等待A锁的释放
print(" funcA:获得了:B锁")
lockB.release()
lockA.release()
def funcB(lockA,lockB):
print(" funcB:需要B锁")
lockB.acquire()
time.sleep(0.2)
print(" funcB:获得了:B锁")
print(" funcB:需要A锁") # A锁 在funcA
lockA.acquire() # A锁 在funcA中被占有,而在funcA中又在等待B锁的释放
print(" funcB:获得了:A锁")
lockA.release()
lockB.release()
def main():
lockA = Lock()
lockB = Lock()
t_a = Thread(target=funcA, args=(lockA, lockB,))
t_a.start()
t_b = Thread(target=funcB, args=(lockA, lockB,))
t_b.start()
print("结束主线程")
if __name__ == "__main__":
main()
2.3:递归锁:RLock
# -*- coding: utf-8 -*-
from threading import Thread
from multiprocessing import Lock
import os
import time
from threading import Thread,RLock # 递归锁
import time
def funcA(lockA,lockB):
print(" funcA:需要A锁")
lockA.acquire()
time.sleep(0.2)
print(" funcA:获得了:A锁")
print(" funcA:需要B锁")
lockB.acquire()
print(" funcA:获得了:B锁")
lockB.release()
lockA.release()
def funcB(lockA,lockB):
print(" funcB:需要B锁")
lockB.acquire()
time.sleep(0.2)
print(" funcB:获得了:B锁")
print(" funcB:需要A锁")
lockA.acquire()
print(" funcB:获得了:A锁")
lockA.release()
lockB.release()
def main():
lockA = lockB = RLock()
t_a = Thread(target=funcA, args=(lockA, lockB,))
t_a.start()
t_b = Thread(target=funcB, args=(lockA, lockB,))
t_b.start()
print("结束主线程")
if __name__ == "__main__":
main()
2.4:信号量:BoundedSemaphore
互斥锁同时只允许一个线程更改数据,而信号量是同时允许多少个线程同时运行。
# -*- coding: utf-8 -*-
from threading import Thread,BoundedSemaphore,active_count
import time
def func(index, semaphore):
semaphore.acquire() #加锁
print(f"线程:{index} 运行中...,当前活动线程数:{active_count()}")
time.sleep(5) # 为了看到效果,休眠久点
semaphore.release() #释放
def main():
semaphore = BoundedSemaphore(3) # 最多允许3个线程同时运行
for i in range(20):
t = Thread(target=func, args=(i, semaphore))
t.start()
print(f"主线程:当前活动线程数:{active_count()}")
if __name__ == '__main__':
main()
2.5:事件:Event
# -*- coding: utf-8 -*-
import time
from threading import Thread,Event
def light(e):
while 1:
print('现在是红灯:')
time.sleep(5)
e.set() # 设置event的状态值为True ;
print('现在是绿灯:')
time.sleep(3)
e.clear() # 恢复event的状态值为False。
def car(index,e):
if e.is_set(): # 返回event的状态值;
# 状态为True
print(f' 现在是绿灯,{index}:过马路中!')
else:
print(f' 现在是红灯{index}:等待中!')
e.wait() # 如果 event.isSet()==False将阻塞
print(f' 红灯变绿灯,{index}:可以走了!')
def main():
e = Event()
lgh = Thread(target=light, args=(e,))
lgh.start()
cnt = 0
while 1:
time.sleep(1) # 每隔1秒来一辆car
t1 = Thread(target=car, args=(cnt, e,))
t1.start()
cnt += 1
if __name__ == '__main__':
main()
2.6:线程池
2.6.1:submit方法
# -*- coding: utf-8 -*-
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time
from threading import current_thread
def func(index):
# print(index,current_thread().ident)
time.sleep(0.1)
return [index,index**2]
if __name__ == "__main__":
t_p = ThreadPoolExecutor(max_workers=6)
t_ret_list = []
for i in range(20):
t = t_p.submit(func, i)
t_ret_list.append(t)
for ret in t_ret_list:
print(ret.result())
2.6.2:map方法
# -*- coding: utf-8 -*-
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import time
from threading import current_thread
def func(index):
# print(index,current_thread().ident)
time.sleep(0.1)
return [index,index**2]
if __name__ == "__main__":
t_p = ThreadPoolExecutor(max_workers=6)
map_ret = t_p.map(func,range(20))
print(map_ret)
for ret in map_ret:
print(ret)
Python3并发编程-多线程threading怎么用?相关推荐
- python 并发编程 多线程 目录
线程理论 python 并发编程 多线程 开启线程的两种方式 python 并发编程 多线程与多进程的区别 python 并发编程 多线程 Thread对象的其他属性或方法 python 并发编程 多 ...
- java虚拟机线程调优与底层原理分析_Java并发编程——多线程的底层原理
" Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和 CPU的 ...
- java 并发编程多线程_多线程(一)java并发编程基础知识
线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...
- Java并发编程(多线程)中的相关概念
众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试中必问的题,一个好的Java程序员是必须对并发编程这块有所了解的. 并发必须知道的概念 在深入学习并发编程之前,我们需要了解几个基本 ...
- 并发编程-多线程基础
1.引言 推荐书籍 深入理解Java并发编程 Java并发编程 核心知识点 多线程基础知识 同步和异步的概念 线程安全(线程同步)相关 线程通讯 java1.8并发包 线程池原理分析 锁的概念 专题类 ...
- java并发编程:多线程基础
文章目录 并发编程三要素 并发编程内存模型 多线程 创建线程的三种方式 volatile synchronized 线程池 ThreadPoolExcutor![在这里插入图片描述](https:// ...
- python3并发编程基础
1.基本概念 1.串行与并行 a.串行:比喻是一个人在同一时间段只能干一件事,如只能吃完饭后再玩手机 b.并行:比喻是一个人在同一时间段可以干很多事,如一边吃饭一边玩手机 2.在python中,多线程 ...
- Python网络与并发编程 10 threading模块线程锁
前言 本章节将继续围绕threading模块讲解,基本上是纯理论偏多. 对于日常开发者来讲很少会使用到本章节的内容,但是对框架作者等是必备知识,同时也是高频的面试常见问题. 官方文档 线程安全 线程安 ...
- python线程池并发_python 并发编程多线程之进程池/线程池
一.验证GIL锁的存在 Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行.虽然 Python 解释器中可以"运行"多个线程,但在任意时刻只有一个线程在解释器中运行 ...
最新文章
- Karto的前端实现与解读
- Android4.2.2源码目录结构分析
- 也读《人月神话》:没有银弹的软件工程
- Distinct源码分析
- r语言查找是否存在空值_关于R包安装你知道多少?
- 2008最新热门搞笑的50条语录
- 镜像电流源特点_电流源传奇——镜之分身
- 64qam带宽计算_64QAM有效传输速率计算
- 暖心的坚果 Pro 3发布会,Smartisan OS亮点颇多
- hadoop分布式安装部署具体视频教程(网盘附配好环境的CentOS虚拟机文件/hadoop配置文件)...
- 如何下载网页上的图片
- WIN10下如何更改微信聊天记录的默认存储路径
- 百度闪电算法什么时间开始
- 解决原先mysql与wampserver中mysql冲突问题
- Mac出现异常,如何在M1或Intel Mac上重置NVRAM
- Qt QTcpSocket 客户端设计(自动重连、多线程处理、发送大数据包、同步方式)
- A - Rooms and Passages Gym - 102215A
- 博士毕业选择回老家县城大专任教!事业编、副教授待遇、外加几十万安家费......
- js 中的in_array
- 完美修改VS2019注释快捷键
热门文章
- iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
- 生成器案例,#采集日志
- Redis和Memcached的区别详解
- 《技术的潜能:商业颠覆、创新与执行》一一2.12决心、愿望和耐力
- 学习了时间和测试题目
- Android SubsamplingScaleImageView(subsampling-scale-image-view)单双击长按事件【系列2】
- 安装nodejs express框架时express命令行无效
- IE7下面 overflow:hidden 无效
- Mongodb 与sql 语句对照
- 在CentOS上安装NodeJS_v14.x