No.1 线程
什么是多任务
就是操作系统可以同时运行多个任务,就是可以一边用浏览器上网,同时又可以听歌,还能再撩个×××姐,这就是多任务,操作系统会轮流把系统调度到每个核心上去执行
并发和并行
并发是指任务数多余cpu核数,通过操作系统的各种任务调度算法,实现多个任务
并行是指任务数小于cpu核数,即任务同时执行
单线程
import time
def say_hello(i):
print('hello ', i)
if __name__ == '__main__':
for i in range(5):
say_hello(i)
多线程
import threading
import time
def say_hello(i):
print('hello ', i)
if __name__ == '__main__':
for i in range(5):
t = threading.Thread(target=say_hello,args=(i,))
t.start() # 当调用start方法时,才会正真的执行线程
主线程会等待子线程
import threading
import time
def say_hello(name):
for i in range(5):
print('hello ', i, name)
if __name__ == '__main__':
say_hello('主线程')
t1 = threading.Thread(target=say_hello,args=('t1',))
t2 = threading.Thread(target=say_hello,args=('t2',))
t1.start()
t2.start()
print('end')
# hello 0 主线程
# hello 1 主线程
# hello 2 主线程
# hello 3 主线程
# hello 4 主线程
# hello 0 t1
# hello 1 t1
# hello 2 t1
# hello 3 t1
# hello 4 t1
# hello 0 t2
# hello 1 t2
# hello 2 t2
# hello 3 t2
# hello 4 t2
# end
查看线程数量
import threading
import time
def say_hello(i):
print('hello ', i)
if __name__ == '__main__':
say_hello('主线程')
for i in range(5):
t = threading.Thread(target=say_hello,args=(i,))
t.start()
while True:
length = len(threading.enumerate())
print('当前运行的线程数为:%d' % length)
if length <= 1:
break
# hello 主线程
# hello 0
# 当前运行的线程数为:2
# 当前运行的线程数为:1
# hello 1
# 当前运行的线程数为:1
# hello 2
# 当前运行的线程数为:1
# hello 3
# 当前运行的线程数为:1
# hello 4
# 当前运行的线程数为:1
封装线程
为了让每个线程的封装性更加完整,我们通常会创建一个线程类,让这个线程类继承自threading.Thread,然后重写run方法就可以了
import threading
import time
class MyThread(threading.Thread):
def run(self):
for i in range(5):
time.sleep(1)
print(self.name + str(i))
if __name__ == '__main__':
t = MyThread()
t.start()
Python的threading.Thread类的run方法,用于定义线程的功能函数,可以在我们自己的类中覆盖该方法,当创建自己的线程类对象后,可以start方法,进行调度
线程的执行顺序
线程的执行顺序是不确定的,当执行到sleep语句时,线程将会被阻塞,然后线程进入就绪状态,等待cpu的调度,线程调度自动选择一个线程执行
No.2 多线程
多线程共享全局变量
import threading
import time
num = 100
def demo1():
global num
for i in range(3):
num -= 1
print('num = ',num)
def demo2():
print('num = ', num)
if __name__ == '__main__':
print('线程创建之前num = ',num)
t1 = threading.Thread(target=demo1)
t1.start()
time.sleep(1)
t2 = threading.Thread(target=demo2)
t2.start()
# 线程创建之前num = 100
# num = 99
# num = 98
# num = 97
# num = 97
在一个进程内的所有线程共享全局变量,能很方便的在多个线程之间共享数据,但是这也带来一个麻烦,就是线程就全局变量的随机修改可能会导致多线程之间对于全局变量的的混乱,即线程非安全
import threading
import time
num = 100
def demo1():
global num
for i in range(1000000):
# lock.acquire()
num += 1
# lock.release()
def demo2():
global num
for i in range(1000000):
# lock.acquire()
num += 1
# lock.release()
if __name__ == '__main__':
print('线程创建之前num = ',num)