今日份学习笔记:用于压测,开发说需要利用线程往redis里面插入数据,接触到python 多线程处理
自己就写了一个hin简单的多线程,
了解到实现多线程的方式有两种
① 给构造函数传递回调对象
②重写Thread类的run()方法
我这里用到的是①
具体步骤如下:
①导入模块
import threading
②创建线程组
threads=[]
③创建一个线程并将线程加入线程组
t =threading.Thread(target=function_name, args=())
function_name:即需要线程去执行的方法名
args:需要执行的方法所需要的参数,该属性是一个元组,当只有一个参数时需要在末尾加入逗号
#线程需要执行的方法
def insert_trans_to_redis1():
"""塞入运单号到redis"""
trans = sel_trans()
re = connect_redis()
if re:
for tr in trans:
re.lpush("camel:waybill:trans:list", tr)
print re.llen("camel:waybill:trans:list")
print u"执行时间1为:%s"%time.ctime()
time.sleep(5)
print u"结束时间1%s"%time.ctime()
def insert_trans_to_redis2():
"""塞入运单号到redis"""
trans = sel_trans()
re = connect_redis()
if re:
for tr in trans:
re.lpush("camel:waybill:trans:list", tr)
print re.llen("camel:waybill:trans:list")
print u"执行时间2为:%s"%time.ctime()
time.sleep(3)
print u"结束时间2%s"%time.ctime()
#线程的创建
threads = []
t1= threading.Thread(target=insert_trans_to_redis1)
#insert_trans_to_redis是我的方法名,不需要参数
threads.append(t1)
t2= threading.Thread(target=insert_trans_to_redis2)
threads.append(t2)
④启动线程
①第一种写法:
for t in threads:
t.setDaemon(True)
t.start()
print "all over %s"%time.ctime()
当子线程结束之后,就退出了,没有执行主线程,为啥呢?执行结果如图1
②第二种写法:
for t in threads:
t.start()
t.join()
print "all over %s"%time.ctime()
当所有线程执行完毕后退出,如图2
③第三种写法
for t in threads:
t.start()
for t in threads:
t.join()
#join()阻塞线程
print u"all over %s"%time.ctime()
当所有子线程运行完毕之后再运行主线程,运行完毕之后再退出,执行结果如图③
通过执行结果可看出②和③的区别
守护线程的概念
守护线程与非守护线程的区别
守护线程:当主线程运行完毕之后,守护线程就会被销毁而导致结束了
非守护线程:主线程运行完毕之后,必须等到子线程运行完才可以,不受主线程运行结束的影响,箱单主线程还需要等待非守护线程
需要强调的是:运行完毕并非终止运行
1.对主进程来说,运行完毕指的是主进程代码运行完毕
2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
详细解释:
1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,
2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。
参考地址:https://www.cnblogs.com/strive-man/p/8678096.html
线程阻塞的概念
阻塞线程join和非阻塞线程不join的区别
join()会阻塞线程,等到最长时间的线程结束之后才会退出或执行后面的,主要看怎么写,可以参考②③