python的threading的使用(join方法,多线程,锁threading.Lock和threading.Condition
一、开启多线程方法一
import threading,time def write1():
for i in range(1,5):
print('1')
time.sleep(1) def write12():
for i in range(1, 5):
print('2')
time.sleep(1) # 给两个函数开一个线程,target后面赋值函数名
t1 = threading.Thread(target=write1)
t2 = threading.Thread(target=write12)
# 使用start函数启动这个线程
t1.start()
t2.start()
# 输出线程数量
print(threading.enumerate())
'''
输出:
1
2
[<_MainThread(MainThread, started 21440)>, <Thread(Thread-1, started 2344)>, <Thread(Thread-2, started 3016)>]
1
2
2
1
2
1
'''
二、开启多线程方法二
import threading,time class Write1Threaq(threading.Thread):
def run(self):
for i in range(1, 5):
print('1----%s',threading.current_thread())
time.sleep(1) class Write2Threaq(threading.Thread):
def run(self):
for i in range(1, 5):
# 输出当前线程的名称
print('2----%s',threading.current_thread())
time.sleep(1) def main():
# 继承自threading.Thread之后,只需要实现run方法,执行start函数后,会自动执行run函数
t1 = Write1Threaq()
t2 = Write2Threaq()
t1.start()
t2.start() if __name__ == '__main__':
main() '''
输出:
1----%s <Write1Threaq(Thread-1, started 6304)>
2----%s <Write2Threaq(Thread-2, started 10524)>
2----%s <Write2Threaq(Thread-2, started 10524)>
1----%s <Write1Threaq(Thread-1, started 6304)>
2----%s <Write2Threaq(Thread-2, started 10524)>
1----%s <Write1Threaq(Thread-1, started 6304)>
1----%s2----%s <Write2Threaq(Thread-2, started 10524)>
<Write1Threaq(Thread-1, started 6304)> '''
三、不上锁会出现的错误情况
import time,threading value = 0
def write():
global value
for i in range(1,1000000):
value+=1
print(value) def main():
for i in range(1,3):
t1 = threading.Thread(target=write)
t1.start() if __name__ == '__main__':
main() '''
输出:
# 输出结果显然不符合我们的预期,例如value等于10的时候,两个线程同时进行了两次value+1,但是这个时候两个value+1的
# value都是10,那么结果value就是11,可以说少加了一次1
1143699
1227119
'''
四、使用Lock进行上锁解决三的问题
import time,threading
# 使用多线程锁
glock = threading.Lock() value = 0
def write():
global value
# 上锁
glock.acquire()
for i in range(1,1000000):
value+=1
# 解锁
glock.release()
print(value) def main():
for i in range(1,3):
t1 = threading.Thread(target=write)
t1.start() if __name__ == '__main__':
main() '''
输出:这样就没问题了
999999
1999998
'''
五、condition的使用
threading.Condition 是一个继承自threading.Lock的一个类,所以它也有上锁解锁的功能,上锁acquire,解锁ralease
同时它还具有wait()函数,其功能为将程序在此处阻塞,可以通过函数notify,或者notify_all来进行唤醒,这两个函数要在release之前调用
notify执行一次只会唤醒一个线程,默认是第一个等待的线程
notify_all执行一次会唤醒所有的线程,
import random,threading,time
gcondition = threading.Condition()
Money = 0
def Create():
global Money
num=0
while 1:
if num>10:
break
gcondition.acquire()
Money += random.randint(1,100)
print('生产Money:',Money)
gcondition.notify_all()
gcondition.release()
num+=1
time.sleep(1)
def Consumer(money):
global Money
num = 0
while 1:
if num>2:
break
gcondition.acquire()
while Money<money:
print('金额不足!')
time.sleep(1)
gcondition.wait()
Money-=money
print('总钱数:%s,花费:%s,剩余:%s。',Money+money,money,Money)
gcondition.release()
num+=1
time.sleep(1)
def main():
for i in range(1, 3):
t1 = threading.Thread(target=Create)
t1.start()
print('---------------------')
for i in range(1, 3):
ans = random.randint(1, 100)
t1 = threading.Thread(target=Consumer,args=[ans])# 注意这里的参数传递方式
t1.start()
if __name__ == '__main__':
main()
'''
生产Money: 18
生产Money: 90
---------------------
总钱数:%s,花费:%s,剩余:%s。 90 84 6
金额不足!
生产Money: 75
生产Money: 105
总钱数:%s,花费:%s,剩余:%s。 105 84 21
金额不足!
生产Money: 107
生产Money: 171
总钱数:%s,花费:%s,剩余:%s。 171 84 87
总钱数:%s,花费:%s,剩余:%s。 87 26 61
生产Money: 146
总钱数:%s,花费:%s,剩余:%s。 146 26 120
生产Money: 181
生产Money: 230
生产Money: 253
总钱数:%s,花费:%s,剩余:%s。 253 26 227
生产Money: 275
生产Money: 320
生产Money: 350
生产Money: 423
生产Money: 431
生产Money: 484
生产Money: 527
生产Money: 596
生产Money: 646
生产Money: 721
生产Money: 788
生产Money: 850
'''
Thread参数传递的问题
错误的参数传递
threading.Thread(target=Consumer(ans))
import random,threading,time gcondition = threading.Condition()
Money = 100
def Create():
global Money
num=0
while 1:
if num>10:
break
gcondition.acquire()
Money += random.randint(1,100)
print('生产Money:',Money)
gcondition.notify_all()
gcondition.release()
num+=1
time.sleep(1) def Consumer(money):
global Money
num = 0
while 1:
if num>2:
break
gcondition.acquire()
while Money<money:
print('金额不足!')
time.sleep(1)
gcondition.wait()
Money-=money
print('总钱数:%s,花费:%s,剩余:%s。',Money+money,money,Money)
gcondition.release()
num+=1
time.sleep(1) def main():
for i in range(1, 3):
print('222')
ans = random.randint(1, 100)
t1 = threading.Thread(target=Consumer(ans))
t1.start()
print('---------------------') for i in range(1, 3):
t1 = threading.Thread(target=Create)
t1.start() if __name__ == '__main__':
main() '''
222
总钱数:%s,花费:%s,剩余:%s。 100 12 88
总钱数:%s,花费:%s,剩余:%s。 88 12 76
总钱数:%s,花费:%s,剩余:%s。 76 12 64
222
总钱数:%s,花费:%s,剩余:%s。 64 57 7
金额不足!
程序将会一直卡到这里,这是因为你这样的参数传递方式相当于在start函数没有执行,函数就开始了运行
'''
正确的参数传递
threading.Thread(target=Consumer,args=[ans])
import random,threading,time gcondition = threading.Condition()
Money = 100
def Create():
global Money
num=0
while 1:
if num>10:
break
gcondition.acquire()
Money += random.randint(1,100)
print('生产Money:',Money)
gcondition.notify_all()
gcondition.release()
num+=1
time.sleep(1) def Consumer(money):
global Money
num = 0
while 1:
if num>2:
break
gcondition.acquire()
while Money<money:
print('金额不足!')
time.sleep(1)
gcondition.wait()
Money-=money
print('总钱数:%s,花费:%s,剩余:%s。',Money+money,money,Money)
gcondition.release()
num+=1
time.sleep(1) def main():
the_list = []
for i in range(1, 3):
ans = random.randint(1, 100)
# 参数传递要这样,可不能写成Thread(target=Consumer(ans))
t1 = threading.Thread(target=Consumer,args=[ans])
#the_list.append(t1)
t1.start()
for i in the_list:
i.start()
print('---------------------') for i in range(1, 3):
t1 = threading.Thread(target=Create)
t1.start() if __name__ == '__main__':
main() '''
总钱数:%s,花费:%s,剩余:%s。 222
100 10 90
总钱数:%s,花费:%s,剩余:%s。 90 17 ---------------------
73
生产Money: 99
生产Money: 141
生产Money: 162
总钱数:%s,花费:%s,剩余:%s。 162 17 145
总钱数:%s,花费:%s,剩余:%s。 145 10 135
生产Money: 164
生产Money: 228
总钱数:%s,花费:%s,剩余:%s。 228 17 211
总钱数:%s,花费:%s,剩余:%s。 211 10 201
生产Money: 203
生产Money: 249
生产Money: 276
生产Money: 321
生产Money: 342
生产Money: 387
生产Money: 475
生产Money: 501
生产Money: 596
生产Money: 682
生产Money: 731
生产Money: 823
生产Money: 888
生产Money: 975
生产Money: 1025
生产Money: 1056
生产Money: 1129
'''
六、join函数
如果一个线程在执行过程中要调用另外一个线程,并且等到其完成以后才能接着执行,解决方法就是“那么在调用这个线程时可以使用被调用线程的join方法。”
下面先说一下setDeamon()吧:
其实主线程并不会结束setDeamon(True)的线程,而是当主线程执行完毕之后不会再去关注setDeamon(True)的线程。
所以setDeamon(True)的线程的结果是我们无法获取到的,类似于爱咋咋地?不管你输出什么,我都不看,主线程跑
完就结束整个python process。
而setDeamon(False)的线程会一直受到主线程的关注,就算主线程跑完了也会等setDeamon(False)的线程跑完然后
再结束整个python process。
所以说,就算setDeamon(True)的线程在主线程之后跑完,但如果在setDeamon(False)的线程之前跑完的话,也是会
输出结果的,而不是被所谓的主线程结束就杀死setDeamon(False)的线程。
看一下不同setDeamon运行结果:
#coding:utf-8
import threading
import time def action(arg):
for i in range(2):
print('sub thread start!the thread name is:%s ' % threading.currentThread().getName())
print('the arg is:%s ' %arg)
time.sleep(1) for i in range(4):
t =threading.Thread(target=action,args=(i,))
t.setDaemon(True)
t.start() print('main_thread end!') '''
setDaemon(True)的输出:
sub thread start!the thread name is:Thread-1
the arg is:0
sub thread start!the thread name is:Thread-2
the arg is:1
sub thread start!the thread name is:Thread-3
the arg is:2
sub thread start!the thread name is:Thread-4
the arg is:3
main_thread end!
'''
'''
setDaemon(False)的输出:
sub thread start!the thread name is:Thread-1
the arg is:0
sub thread start!the thread name is:Thread-2
the arg is:1
sub thread start!the thread name is:Thread-3
the arg is:2
sub thread start!the thread name is:Thread-4
the arg is:3
main_thread end!
sub thread start!the thread name is:Thread-2 sub thread start!the thread name is:Thread-1
the arg is:0 the arg is:1
sub thread start!the thread name is:Thread-3
the arg is:2
sub thread start!the thread name is:Thread-4
the arg is:3
'''
join使用的程序正确书写方法:
#coding:utf-8
import threading
import time def action(arg):
time.sleep(1)
print('sub thread start!the thread name is:%s ' % threading.currentThread().getName())
print('the arg is:%s ' %arg)
time.sleep(1) #不正确写法,会导致多线程顺序执行,失去了多线程的意义
for i in range(4):
t =threading.Thread(target=action,args=(i,))
t.setDaemon(True)
t.start()
t.join() #正确写法
thread_list = [] #线程存放列表
for i in range(4):
t =threading.Thread(target=action,args=(i,))
t.setDaemon(True)
thread_list.append(t) for t in thread_list:
t.start() for t in thread_list:
t.join()
print('main_thread end!')
python的threading的使用(join方法,多线程,锁threading.Lock和threading.Condition的更多相关文章
- python小知识- webbrowser模块 + join()方法
一.join描述 将序列中的元素以指定的字符连接生成一个新的字符串. 语法 语法: ‘sep’.join(seq) 参数说明: sep:分隔符.可以为空 seq:要连接的元素序列.字符串.元组.字典 ...
- Python多线程锁
[Python之旅]第六篇(四):Python多线程锁 python lock 多线程 多线程使用方法 多线程锁 摘要: 在多线程程序执行过程中,为什么需要给一些线程加锁以及如何加锁,下面就来 ...
- Python学习笔记16:标准库多线程(threading包裹)
Python主要是通过标准库threading包来实现多线程. 今天,互联网时代,所有的server您将收到大量请求. server要利用多线程的方式的优势来处理这些请求,为了改善网络port读写效率 ...
- python线程join方法
转载:http://www.cnblogs.com/cnkai/p/7504980.html Python多线程与多进程中join()方法的效果是相同的. 下面仅以多线程为例: 首先需要明确几个概念: ...
- C#多线程JOIN方法初探
[说明:刚接触多线程时,弄不明白Join()的作用,查阅了三本书,都不明不白.后来经过自己的一番试验,终于弄清了Join()的本质.大家看看我这种写法是否易懂,是否真的写出了Join()的本质,多提宝 ...
- python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon)
python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon) 前言 今天小编YOYO请xiaoming和xiaowang吃火锅,吃完火锅的时候会有以下三种场景: - ...
- 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等
java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程 实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...
- python thread的join方法解释
python的Thread类中提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行.这个方法还可以设定一个timeout参数,避免无休止的等待.因为两个线程顺序完成,看起来象一个 ...
- python常错: join() 方法
描述 Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串. 语法 join()方法语法: str.join(sequence) 参数 sequence -- 要连接的 ...
随机推荐
- 在Linux系统下限制指定目录的大小以及文件/文件夹数量
背景说明 在Linux操作系统下有时需要限制一个指定文件夹的大小和文件夹内可存储的文件数量,有可能是出于安全的考量或者定制化的配置,这里我们提供了一种方案:用dd创建一个空的img镜像,进行格式化的配 ...
- 十三:SQL注入之MYSQL注入
MYSQL注入中首先要明确当前注入点权限,高权限注入时有更多的攻击手法,有的能直接进行getshell操作,其中也会遇到很多的阻碍,相关防御手法也要明确,所谓知己知彼,百战不殆.作为安全开发工作者,攻 ...
- Mac Navicat premium 12 连接mysql8.0.21出现 'caching_sha2_password' 解决方案
1.通过命令 select user,plugin from user where user='root'; 我们可以发现加密方式是caching_sha2_password. 2. 修改查看加密方 ...
- 【MySQL】使用WHERE子句 - 过滤数据
第6章 过滤数据 文章目录 第6章 过滤数据 1.使用WHERE子句 2.WHERE子句操作符 2.1.检查单个值 2.2.不匹配检查 2.3.范围值检查 2.4.空值检查 3.小结 简单记录 - M ...
- 【Web】CSS实现鼠标悬停实现显示与隐藏 特效
鼠标悬停实现显示与隐藏特效 简单记录 - 慕课网 Web前端 步骤四:鼠标悬停实现显示与隐藏特效 初步掌握定位的基本使用,以及CSS选择器更高级的运用,完成一个网页中必会的鼠标经过隐藏显示特效. 实现 ...
- HTML DOM 定义了访问和操作 HTML 文档标准
HTML DOM 定义了访问和操作 HTML 文档的标准. 您应该具备的基础知识 在您继续学习之前,您需要对以下内容拥有基本的了解: HTML CSS JavaScript 如果您需要首先学习这些项目 ...
- os-Bytes环境变量劫持
信息收集 netdiscovery -i eth0 nmap -sV -sC 192.168.43.74 -oA os-Bytes gobuster -u 192.168.43.74 -w /usr/ ...
- postgresql数据库升级
pg_upgrade官网介绍:https://www.postgresql.org/docs/10/pgupgrade.html 1.查看老版本数据库编译参数值并记录 select name,sett ...
- widnows2008双网卡双ip不同Ip段
机房内有不同段ip,因为线路不一样,比如普通带宽和cn2带宽,现有需求配置双网卡双ip ip1: 121.7*.*.* 255.255.255.192 121.7*.*129 ip2: 103.11 ...
- C#高级编程第11版 - 第七章 索引
[1]7.1 相同类型的多个对象 1.假如你需要处理同一类型的多个对象,你可以使用集合或者数组. 2.如果你想使用不同类型的不同对象,你最好将它们组合成class.struct或者元组. [2]7.2 ...