多线程 VS 多进程
- 程序: 一堆代码以文本形式存入一个文档
- 进程: 程序运行的一个状态
- 包含地址空间,内存,数据债等
- 每一进程由自己完全独立的运行环境,多进程共享数据是一个问题
- 线程
- 一个进程的独立运行片段,一个进程可以由多个线程
- 轻量化的进程
- 一个进程的多个线程间共享数据和上下文运行环境
- 共享互斥问题
- 全局解释器锁(GIL)
- Python代码的执行是由python虚拟机进行控制
- 在主循环中有切只有一个控制线程在执行
- Python包
- thread : 有问题,不好用,python3改成了_thread
- threading: 通行的包
- 案例01
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
def loopl():
print('Statr loop l at : ', time.ctime())
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2():
print('Start loop 2 at : ', time.ctime())
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
loopl()
loop2()
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
Starting at : Sat Jun 30 14:35:17 2018
Statr loop l at : Sat Jun 30 14:35:17 2018
End loop l at : Sat Jun 30 14:35:21 2018
Start loop 2 at : Sat Jun 30 14:35:21 2018
End loop 2 at : Sat Jun 30 14:35:23 2018
All done at : Sat Jun 30 14:35:23 2018
启用多线程
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
import _thread as thread
def loopl():
print('Statr loop l at : ', time.ctime())
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2():
print('Start loop 2 at : ', time.ctime())
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
thread.start_new_thread(loopl, ())
thread.start_new_thread(loop2, ())
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
time.sleep(5)
Starting at : Sat Jun 30 14:55:11 2018
All done at : Sat Jun 30 14:55:11 2018
Start loop 2 at : Sat Jun 30 14:55:11 2018
Statr loop l at : Sat Jun 30 14:55:11 2018
End loop 2 at : Sat Jun 30 14:55:13 2018
End loop l at : Sat Jun 30 14:55:15 2018
带参数的函数,多线程执行例子
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
import _thread as thread
def loopl(param):
print('Statr loop l at : ', time.ctime())
print("参数 param is :" + param)
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2(name, name2):
print('Start loop 2 at : ', time.ctime())
print("姓名1:" + name, "姓名2 :", name2)
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
thread.start_new_thread(loopl, ("今天天气不错",))
thread.start_new_thread(loop2, ("王大拿","王呵呵"))
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
time.sleep(5)
threading的使用
- 直接利用threading.Thread生成Thread实例
- t = threading.Thread(target=xxx,args=(xxx,))
- t.statr(): 启动多线程
- t.join(): 等待多线程执行完成
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
import threading
def loopl(param):
print('Statr loop l at : ', time.ctime())
print("参数 param is :" + param)
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2(name, name2):
print('Start loop 2 at : ', time.ctime())
print("姓名1:" + name, "姓名2 :", name2)
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
t1 = threading.Thread(target=loopl, args=("老王头",))
t1.start()
t2 = threading.Thread(target=loop2, args=("张芃芃", "李冬面",))
t2.start()
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
Starting at : Sat Jun 30 15:11:00 2018
Statr loop l at : Sat Jun 30 15:11:00 2018
参数 param is :老王头
Start loop 2 at : All done at : Sat Jun 30 15:11:00 2018
Sat Jun 30 15:11:00 2018
姓名1:张芃芃 姓名2 : 李冬面
End loop 2 at : Sat Jun 30 15:11:02 2018
End loop l at : Sat Jun 30 15:11:04 2018
JOIN()用法
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
import threading
def loopl(param):
print('Statr loop l at : ', time.ctime())
print("参数 param is :" + param)
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2(name, name2):
print('Start loop 2 at : ', time.ctime())
print("姓名1:" + name, "姓名2 :", name2)
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
t1 = threading.Thread(target=loopl, args=("老王头",))
t1.start()
t2 = threading.Thread(target=loop2, args=("张芃芃", "李冬面",))
t2.start()
t1.join()
t2.join()
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
守护线程
- 如果在程序中将子线程设置成守护线程,则子线程会在主线程结束的时候自动退出
- 一般认为,守护线程不重要或者不运行离开主线程独立运行
- 守护线程案例能否有效果跟环境相关
import time
import threading
def fun():
print("Strat fun")
time.sleep(2)
print("End fun")
print("Main thread")
t1 = threading.Thread(target=fun, args=())
t1.start()
time.sleep(1)
print("Main thread end")
Main thread
Strat fun
Main thread end
End fun
import time
import threading
def fun():
print("Strat fun")
time.sleep(2)
print("End fun")
print("Main thread")
t1 = threading.Thread(target=fun, args=())
t1.setDaemon(True)
t1.start()
time.sleep(1)
print("Main thread end")
Main thread
Strat fun
Main thread end
End fun
线程常用属性
- threading.currentThread: 返回当前线程变量
- threading.enumerate: 返回一个包含正在运行的线程list,正在运行的线程指的是线程启动后,结束前的线程
- threading.activeCount: 返回正在运行的线程数量
- thr.setName: 设置线程名称
- thr.getName: 获取线程名称
'''
利用time函数,生产两个函数
顺序调用
计算总的运行时间
'''
import time
import threading
def loopl(param):
print('Statr loop l at : ', time.ctime())
print("参数 param is :" + param)
time.sleep(4)
print('End loop l at : ', time.ctime())
def loop2(name, name2):
print('Start loop 2 at : ', time.ctime())
print("姓名1:" + name, "姓名2 :", name2)
time.sleep(2)
print('End loop 2 at : ', time.ctime())
def main():
print('Starting at : ', time.ctime())
t1 = threading.Thread(target=loopl, args=("老王头",))
t1.setName("THR_1_loop1")
t1.start()
t2 = threading.Thread(target=loop2, args=("张芃芃", "李冬面",))
t2.setName("THR_2_loop2")
t2.start()
time.sleep(3)
for thr in threading.enumerate():
print("正在运行的线程名字是: {0}".format(thr.getName()))
print("正在运行的子线程数量为:{0}".format(threading.activeCount()))
print('All done at : ', time.ctime())
if __name__ == '__main__':
main()
Starting at : Sat Jun 30 15:39:41 2018
Statr loop l at : Sat Jun 30 15:39:41 2018
参数 param is :老王头
Start loop 2 at : Sat Jun 30 15:39:41 2018
姓名1:张芃芃 姓名2 : 李冬面
End loop 2 at : Sat Jun 30 15:39:43 2018
正在运行的线程名字是: MainThread
正在运行的线程名字是: Thread-2
正在运行的线程名字是: Thread-3
正在运行的线程名字是: IPythonHistorySavingThread
正在运行的线程名字是: Thread-1
正在运行的线程名字是: THR_1_loop1
正在运行的子线程数量为:6
All done at : Sat Jun 30 15:39:44 2018
End loop l at : Sat Jun 30 15:39:45 2018
直接继承自threading.Thread
- 直接继承Thread
- 重写run()
- 类实例可以直接运行
普通写法
import threading
import time
class ThreadFunc(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global n, lock
time.sleep(1)
if lock.acquire():
print(n,self.name)
n, self.name
n += 1
lock.release()
if "__main__" == __name__:
n = 1
ThreadList = []
lock = threading.Lock()
for i in range(1, 200):
t = ThreadFunc()
ThreadList.append(t)
for t in ThreadList:
t.start()
for t in ThreadList:
t.join()
企业写法
import threading
from time import sleep, ctime
loop = [4, 2]
class ThreadFunc:
def __init__(self, name):
self.name = name
def loop(self, nloop, nsec):
'''
:param nloop: loop函数的名称
:param nsec: 系统休眠时间
:return:
'''
print("Start loop ", nloop, 'at ', ctime())
sleep(nsec)
print("Done loop ", nloop, 'at ', ctime())
def main():
print("Starting at ", ctime())
t = ThreadFunc("loop")
t1 = threading.Thread(target=t.loop, args=('LOOP1', 4))
t2 = threading.Thread(target=ThreadFunc('loop').loop, args=('LOOP2', 2))
t1.start()
t2.start()
t1.join()
t2.join()
print("ALL done at ", ctime())
if __name__ == '__main__':
main()
Starting at Sat Jun 30 16:00:49 2018
Start loop LOOP1 at Sat Jun 30 16:00:49 2018
Start loop LOOP2 at Sat Jun 30 16:00:49 2018
Done loop LOOP2 at Sat Jun 30 16:00:51 2018
Done loop LOOP1 at Sat Jun 30 16:00:53 2018
ALL done at Sat Jun 30 16:00:53 2018