python 包之 threading 多线程
作者:autofelix 发布时间:2021-06-03 19:54:41
标签:python,包,threading,多线程
一、创建一个线程
通过实例化
threading.Thread
类创建线程
import threading
def func(s):
print(s)
if __name__ == '__main__':
# 创建线程
thread = threading.Thread(target=func, args=('hello',))
# 启动线程
thread.start()
# 等待线程结束
thread.join()
二、创建多个线程
import threading
def func(s):
print(s)
if __name__ == '__main__':
thread = [
threading.Thread(target=func, args=('1', ))
threading.Thread(target=func, args=('2', ))
]
[t.start() for t in thread]
[t.join() for t in thread]
三、线程同步
使用锁实现线程同步
threading.Lock
是直接通过_thread模块扩展实现的锁只有“锁定”和“非锁定”两种状态
同一个线程获取锁后,如果在释放锁之前再次获取锁会导致当前线程阻塞,除非有另外的线程来释放锁,如果只有一个线程,并且发生了这种情况,会导致这个线程一直阻塞下去,即形成了死锁。
import time
import threading
# 创建锁
lock = threading.Lock()
# 全局变量
global_resource = [None] * 5
def change_resource(para, sleep):
# 请求锁
lock.acquire()
# 这段代码如果不加锁,第一个线程运行结束后global_resource中是乱的,输出为:结果是: ['hello', 'hi', 'hi', 'hello', 'hello']
# 第二个线程运行结束后,global_resource中还是乱的,输出为:结果是: ['hello', 'hi', 'hi', 'hi', 'hi']
global global_resource
for i in range(len(global_resource)):
global_resource[i] = para
time.sleep(sleep)
print("结果是:", global_resource)
# 释放锁
lock.release()
if __name__ == '__main__':
thread = [
threading.Thread(target=change_resource, args=('hi', 2))
threading.Thread(target=change_resource, args=('hello', 1))
]
[t.start() for t in thread]
[t.join() for t in thread]
# 结果是: ['hi', 'hi', 'hi', 'hi', 'hi']
# 结果是: ['hello', 'hello', 'hello', 'hello', 'hello']
四、递归锁
上面线程同步使用的是普通锁,也就是只有锁的状态,并不知道是哪个线程加的锁
这样的话使用普通锁时,对于一些可能造成死锁的情况,可以考虑使用递归锁来解决
递归锁和普通锁的差别在于加入了“所属线程”和“递归等级”的概念
释放锁必须有获取锁的线程来进行释放
import time
import threading
# 使用成一个递归锁就可以解决当前这种死锁情况
rlock_hi = rlock_hello = threading.RLock()
def test_thread_hi():
# 初始时锁内部的递归等级为1
rlock_hi.acquire()
print('线程test_thread_hi获得了锁rlock_hi')
time.sleep(2)
# 如果再次获取同样一把锁,则不会阻塞,只是内部的递归等级加1
rlock_hello.acquire()
print('线程test_thread_hi获得了锁rlock_hello')
# 释放一次锁,内部递归等级减1
rlock_hello.release()
# 这里再次减,当递归等级为0时,其他线程才可获取到此锁
rlock_hi.release()
def test_thread_hello():
rlock_hello.acquire()
print('线程test_thread_hello获得了锁rlock_hello')
time.sleep(2)
rlock_hi.acquire()
print('线程test_thread_hello获得了锁rlock_hi')
rlock_hi.release()
rlock_hello.release()
if __name__ == '__main__':
thread = [
threading.Thread(target=test_thread_hi)
threading.Thread(target=test_thread_hello)
]
[t.start() for t in thread]
[t.join() for t in thread]
五、信号锁
一个信号量管理一个内部计数器
acquire()
方法会减少计数器,release()
方法则增加计数器计数器的值永远不会小于零
当调用
acquire()
时,如果发现该计数器为零,则阻塞线程直到调用
release()
方法使计数器增加。
import time
import threading
# 创建信号量对象,初始化计数器值为3
semaphore3 = threading.Semaphore(3)
def thread_semaphore(index):
# 信号量计数器减1
semaphore3.acquire()
time.sleep(2)
print('thread_%s is running...' % index)
# 信号量计数器加1
semaphore3.release()
if __name__ == '__main__':
# 虽然会有9个线程运行,但是通过信号量控制同时只能有3个线程运行
# 第4个线程启动时,调用acquire发现计数器为0了,所以就会阻塞等待计数器大于0的时候
for index in range(9):
threading.Thread(target=thread_semaphore, args=(index, )).start()
来源:https://blog.51cto.com/autofelix/5167799


猜你喜欢
- 常用方法#记住引入numpy时要是用别名np,则所有的numpy字样都要替换 #查询数值类型>>>type(float)d
- 概述在pytorch中有两种方式可以保存推理模型,第一种是只保存模型的参数,比如parameters和buffers;另外一种是保存整个模型
- 为了得到更好的网络,学习率通常是要调整的,即刚开始用较大的学习率来加快网络的训练,之后为了提高精确度,需要将学习率调低一点。如图所示,步长(
- Python当中并无switch语句,本文研究的主要是通过字典实现switch语句的功能,具体如下。switch语句用于编写多分支结构的程序
- 本文实例为大家分享了python策略模式代码,供大家参考,具体内容如下"""策略模式""&
- 在cmd下运行go程序或者是GOLAND的Terminal下运行go程序会出现中文乱码的情况。go run ttypemain.go����
- 说明: (1)Linux版本Linux version 2.6.32.12-0.7-default (geeko@buildhost) (g
- 官方说明链接:https://intellij-support.jetbrains.com/hc/en-us/community/posts
- 很多朋友在做特效网页的时候需要用到雪花飘落的效果,我们这里给大家整理了分别用JS还有JQuery两种代码实现这个效果的方式。我们先来看一下需
- 本篇概要1.线程与多线程2.进程与多进程3.多线程并发下载图片4.多进程并发提高数字运算关于并发在计算机编程领域,并发编程是一个很常见的名词
- 本文实例讲述了php字符串函数 str类常见用法。分享给大家供大家参考,具体如下:str_split(string, leg);//将一个字
- 介绍每当我使用pandas进行分析时,我的第一个目标是使用众多可用选项中的一个将数据导入Pandas的DataFrame 。对于绝大多数情况
- 学习完如何生成一个 excel 文件之后,接下来我们继续学习一下如何在 excel 文件中写入一个比较简单的图表,先来看一下所需要的几个函数
- 一个小的解决方法分享:正常安装的情况下,你所需要的包都能在python文件夹下找到,找到你所需要的包 ,把它复制到Python35\Lib\
- 一、前言 英语单词之间是通过空格分隔的,但是中文却不存在空格的概念,因此需要
- 本文主要向大家介绍的是正确优化SQL Server数据库的经验总结,其中包括在对其进行优化的实际操作中值得大家注意的地方描述,以及对SQL语
- 引言现在本地创建一个excel表,以及两个sheet,具体数据如下:sheet1: sheet2:读取excel文件pandas.
- 单位内部网站第三次修改,即将进入尾声,遇到一个怪现象,就是在自定义标签中,加入链接会被替换掉成这样的格式{$GetInstallDir}ad
- 本文目的是由浅入深地介绍python装饰器原理装饰器(Decorators)是 Python 的一个重要部分其功能是,在不修改原函数(类)定
- MYSQL的事务处理主要有两种方法。 1、用begin,rollback,commit来实现 begin 开始一个事务 rollback 事