程序同时执行多个任务
-
使用线程可以把占据长时间的程序中的任务放到后台去处理。
-
程序的运行速度可能加快
一、线程实现方法
线程是CPU分配资源的基本单位。当一程序开始运行,这个程序就变成了一个进程,而一个进程相当于一个或者多个线程。当没有多线程编程时,一个进程相当于一个主线程;当有多线程编程时,一个进程包含多个线程(含主线程)。使用线程可以实现程序大的开发。
-
线程是执行单位,也是最小的资源分配单位。
(一)多线程执行程序
- 单线程执行程序
def demo1():
for i in range(5):
print("demo1:",i)
def demo2():
for i in range(5):
print("demo2:",i)
if __name__ == '__main__':
demo1()
demo2()
- 修改为多线程之后
import threading
def demo1():
for i in range(5):
print("demo1在执行:", i)
def demo2():
for i in range(5):
print("demo2在执行:", i)
def main():
t1 = threading.Thread(target=demo1, name="demo1")
t2 = threading.Thread(target=demo2, name="demo2")
t1.start()
t2.start()
if __name__ == '__main__':
main()
(二)通过继承的方式实现
from threading import Thread
class Thread_Spider1(Thread):
def run(self):
for i in range(5):
print("子线程开始执行", i)
class Thread_Spider2(Thread):
def run(self):
for i in range(5):
print("子线程开始执行", i)
if __name__ == '__main__':
t1 = Thread_Spider1()
t1.start()
t2 = Thread_Spider2()
t2.start()
for i in range(5):
print("主线程:", i)
二、线程的常用方法
方法名称 | 描述 |
---|---|
threading.current_thread() | 获取当前线程对象 |
threading.enumerate() | 获取当前线程的信息 |
getName() | 获取线程名称 |
setName(name) | 设置线程名称 |
(一)threading.current_thread()
- 获取当前线程对象
import threading
class Thread_Spider1(threading.Thread):
def run(self):
thread = threading.current_thread()
print(thread)
# <Thread_Spider1(Thread-1, started 9172)>
for i in range(5):
print("子线程开始执行", i)
class Thread_Spider2(threading.Thread):
def run(self):
thread = threading.current_thread()
print(thread)
# <Thread_Spider2(Thread-2, started 1304)>
for i in range(5):
print("子线程开始执行", i)
if __name__ == '__main__':
t1 = Thread_Spider1()
t1.start()
t2 = Thread_Spider2()
t2.start()
for i in range(5):
print("主线程:", i)
-----------------------------
<Thread_Spider(Thread-1, started 7936)>
子线程1开始执行 0
<Thread_Spider2(Thread-2, started 15784)>主线程:
子线程2开始执行 0
0
子线程1开始执行子线程2开始执行主线程: 1
1
1
子线程2开始执行子线程1开始执行主线程: 2
2
2
子线程1开始执行子线程2开始执行主线程: 3 3
3
子线程2开始执行主线程: 44
子线程1开始执行
4
(二)threading.enumerate()
- 获取当前线程的信息
import threading
class Thread_Spider1(threading.Thread):
def run(self):
for i in range(5):
print("子线程开始执行", i)
class Thread_Spider2(threading.Thread):
def run(self):
for i in range(5):
print("子线程开始执行", i)
if __name__ == '__main__':
t1 = Thread_Spider1()
t1.start()
t2 = Thread_Spider2()
t2.start()
print(threading.enumerate())
# [<_MainThread(MainThread, started 3088)>, <Thread_Spider1(Thread-1, started 9040)>, <Thread_Spider2(Thread-2, started 6376)>]
for i in range(5):
print("主线程:", i)
---------------------------------------------------------
子线程1开始执行 0
子线程2开始执行[<_MainThread(MainThread, started 7764)>, <Thread_Spider(Thread-1, started 19600)>, <Thread_Spider2(Thread-2, started 13336)>]
主线程: 0
0
子线程1开始执行子线程2开始执行主线程: 1
1
1
子线程1开始执行子线程2开始执行 主线程:2
2
2
子线程1开始执行子线程2开始执行 3主线程:3
3
子线程1开始执行子线程2开始执行主线程: 4
4
4
(三)修改以及获取名称
了解即可
import threading
class Thread_Spider1(threading.Thread):
def run(self):
thread = threading.current_thread()
print(thread)
print("线程名称:", thread.getName())
thread.setName("我的子线程")
print("修改后的名称:", thread.getName())
for i in range(5):
print("子线程开始执行", i)
if __name__ == '__main__':
t1 = Thread_Spider1()
t1.start()
print(threading.enumerate())
for i in range(5):
print("主线程:", i)
三、共享全局变量资源竞争
- 多个线程同时在完成一个任务的时候发生资源竞争。
import threading
num = 100
def func1():
for i in range(200):
global num
if num > 0:
print("func1-正在输出{}".format(num))
num -= 1
def func2():
for i in range(200):
global num
if num > 0:
print("func2-正在输出{}".format(num))
num -= 1
def func3():
for i in range(200):
global num
if num > 0:
print("func3-正在输出{}".format(num))
num -= 1
def start():
t1 = threading.Thread(target=func1)
t1.start()
t2 = threading.Thread(target=func2)
t2.start()
t3 = threading.Thread(target=func2)
t3.start()
if __name__ == '__main__':
start()
四、锁机制
- 解决多线程访问全局变量的安全性问题。
- 访问全局变量无需加锁,修改时需要加锁,修改完毕之后要释放锁。
-
加锁步骤
- 创建加锁对象threading.Lock()。
- 加锁acquire()。
- 解锁release()。
import threading
num = 100
lock = threading.Lock()
def func1():
for i in range(200):
global num
lock.acquire()
if num > 0:
print("func1-正在输出{}".format(num))
num -= 1
lock.release()
def func2():
for i in range(200):
global num
lock.acquire()
if num > 0:
print("func2-正在输出{}".format(num))
num -= 1
lock.release()
def func3():
for i in range(200):
global num
lock.acquire()
if num > 0:
print("func3-正在输出{}".format(num))
num -= 1
lock.release()
def start():
t1 = threading.Thread(target=func1)
t1.start()
t2 = threading.Thread(target=func2)
t2.start()
t3 = threading.Thread(target=func2)
t3.start()
if __name__ == '__main__':
start()
标签:__,Thread,threading,num,线程,print,多线程 From: https://www.cnblogs.com/LoLong/p/16897857.html