一、前言
一个程序至少有一个主线程,主线程启动子线程后,它们之间并没有隶属关系。主线程和子线程执行是并行的,相互独立。主线程执行完毕后默认不等子线程执行结束就接着往下走了,如果有其他程序就会运行另外的程序,如果没有就等待子线程执行完成后结束程序。
import threading
import time
import random
class MyThread(threading.Thread):
def __init__(self, n):
super(MyThread, self).__init__()
self.n = n
def run(self):
print('task %s is operating' % self.n)
t_time = random.randint(1, 8)
time.sleep(t_time)
# getNname获取线程名称
print(self.getName(), 'finished', 'I sleep %d seconds' % t_time)
class Person(object):
def __init__(self, name):
self.name = name
def get_info(self):
# time.sleep(10)
print('my name is %s.' % self.name)
if __name__ == '__main__':
start_time = time.time()
for i in range(5):
t = MyThread(i)
t.start()
# t.join()
print('main thread finished.')
print('*****执行另一个程序了******')
p = Person('bigberg')
p.get_info()
print('*************************')
print('cost: %s' % (time.time() - start_time))
结果:
# 线程开始执行
task 0 is operating
task 1 is operating
task 2 is operating
task 3 is operating
task 4 is operating
# 主线程执行完毕
main thread finished.
# 可以执行另一个程序了
*****执行另一个程序了******
my name is bigberg.
*************************
# 这里花费的时间是主线程的运行时间,显然没有计算子线程的时间
cost: 0.0019881725311279297
# 子线程在主线程结束后依然在运行
Thread-3 finished I sleep 2 seconds
Thread-5 finished I sleep 2 seconds
Thread-2 finished I sleep 3 seconds
Thread-4 finished I sleep 4 seconds
Thread-1 finished I sleep 5 seconds
# 所有子线程完毕后程序结束
Process finished with exit code 0
二、join 等待子线程完成
如果在线程实例后加上join默认主线程是阻塞的,主线程会等待该子线程运行完成后在结束。
# -*- coding: UTF-8 -*-
import threading
import time
import random
class MyThread(threading.Thread):
def __init__(self, n):
super(MyThread, self).__init__()
self.n = n
def run(self):
print('task %s is operating' % self.n)
t_time = random.randint(1, 8)
time.sleep(t_time)
print(self.getName(), 'finished', 'I sleep %d seconds' % t_time)
if __name__ == '__main__':
start_time = time.time()
for i in range(5):
t = MyThread(i)
t.start()
t.join() # 添加join,阻塞主线程
print('main thread finished.')
print('cost: %s' % (time.time() - start_time))
# 注
# 如果对每个线程都加join,那么并发就没有了,实际上线程都是串行的
# 前一个线程执行完了,才会执行下一个线程
# 主线程最后运行完毕
结果:
task 0 is operating
Thread-1 finished I sleep 2 seconds
task 1 is operating
Thread-2 finished I sleep 6 seconds
task 2 is operating
Thread-3 finished I sleep 4 seconds
task 3 is operating
Thread-4 finished I sleep 8 seconds
task 4 is operating
Thread-5 finished I sleep 5 seconds
# 这里主线程已经是最后执行完毕的了
main thread finished.
# 消耗的时间也是每个线程的运行时间之和
cost: 25.005265712738037
2.1 计算并发运行时间
如果不想计算出总的运行时间,而是所有线程的并发运行时间呢?就像上例中的那样,最长运行时间是8秒,那么所有线程都能在8秒内全部运行完毕。
把t.join()单独移到for循环外面是不行的,因为这样并发运行总会在最后一个线程出阻塞。如下:
# -*- coding: UTF-8 -*-
import threading
import time
import random
class MyThread(threading.Thread):
def __init__(self, n):
super(MyThread, self).__init__()
self.n = n
def run(self):
print('task %s is operating' % self.n)
t_time = random.randint(1, 8)
time.sleep(t_time)
print(self.getName(), 'finished', 'I sleep %d seconds' % t_time)
if __name__ == '__main__':
start_time = time.time()
for i in range(5):
t = MyThread(i)
t.start()
t.join() # 添加join,阻塞主线程
print('main thread finished.')
print('cost: %s' % (time.time() - start_time))
结果:
task 0 is operating
task 1 is operating
task 2 is operating
task 3 is operating
task 4 is operating
Thread-1 fin