python进阶--多线程
发布日期:2021-05-14 12:22:38 浏览次数:20 分类:精选文章

本文共 4848 字,大约阅读时间需要 16 分钟。

多线程与多进程的比较与多线程应用

文章目录

1. 多线程 vs 多进程

  • 多线程: 一个进程的独立运行片段,一个进程可以由多个线程
  • 多进程: 程序运行的一个状态,包含地址空间,内存,数据栈等
  • 线程与进程的区别: 线程是进程的一种轻量化形式,共享数据与上下文

2. 全局解释器锁(GIL)

  • GIL:在CPython中,解释器的全局锁,保证单线程执行
  • Python多核性能问题:GIL导致多线程无法充分利用多核资源
  • IO密集型任务:适合使用多线程,如网络、磁盘IO等

3. Python多线程实践

3.1 使用 _thread

import _thread
def loop1(in1):
time.sleep(4)
def loop2(in1, in2):
time.sleep(2)
# 启动多线程
_thread.start_new_thread(loop1, ("王老大",))
_thread.start_new_thread(loop2, ("王大鹏", "王晓鹏"))

3.2 使用 threading

import threading
t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
# 等待子线程结束
t1.join()
t2.join()
print(threading.activeCount())

3.3 守护线程

import threading
def func():
print("start fun")
time.sleep(2)
print("end fun")
# 非守护线程
t1 = threading.Thread(target=func)
t1.start()
print("main thread end")
# 守护线程
t2 = threading.Thread(target=func)
t2.setDaemon(True)
t2.start()
print("main thread end")

4. 多线程的共享与同步

4.1 线程共享问题

import threading
sum = 0
n = 1000000
# 非安全共享
t1 = threading.Thread(target=Add)
t2 = threading.Thread(target=Minu)
t1.start()
t2.start()
t1.join()
t2.join()
print(sum)

4.2 线程互斥锁

import threading
lock = threading.Lock()
sum = 0
n = 1000000
# 安全共享
def Add():
for i in range(n):
lock.acquire()
sum += 1
lock.release()
def Minu():
for i in range(n):
lock.acquire()
sum -= 1
lock.release()
t1 = threading.Thread(target=Add)
t2 = threading.Thread(target=Minu)
t1.start()
t2.start()
t1.join()
t2.join()
print(sum)

5. 常见线程问题

5.1 线程死锁

import threading
import time
lock_1 = threading.Lock()
lock_2 = threading.Lock()
def func_1():
print("func_1:申请锁1...")
lock_1.acquire()
print("func_1:申请锁2...")
try:
lock_2.acquire()
print("func_1:运行中...")
time.sleep(2)
finally:
lock_1.release()
def func_2():
print("func_2:申请锁2...")
lock_2.acquire()
print("func_2:申请锁1...")
try:
lock_1.acquire()
print("func_2:运行中...")
time.sleep(4)
finally:
lock_2.release()
# 定时启动线程
t1 = threading.Thread(target=func_1)
t2 = threading.Thread(target=func_2)
t1.start()
t2.start()

6. 线程的拓展

6.1 Semaphore(信号量)

import threading
import time
semaphore = threading.Semaphore(3)
def func():
if semaphore.acquire():
print(threading.current_thread().name + "获取信号量")
time.sleep(2)
semaphore.release()
print(threading.current_thread().name + "释放信号量")
# 启动8个线程
for i in range(8):
t = threading.Thread(target=func)
t.start()

6.2 Timer(定时任务)

import threading
import time
def func():
print("I am running.........")
time.sleep(4)
print("I am done......")
if __name__ == "__main__":
timer = threading.Timer(6, func)
timer.start()
i = 0
while True:
print(str(i) + "***************")
time.sleep(3)
i += 1

7. GIL与多线程性能

  • GIL:CPython中的全局解释器锁,限制了多线程的执行
  • 适用场景
    • CPU密集型任务:不适合,GIL导致多线程效率低
    • IO密集型任务:适合,IO任务可以有效分摊到多个线程

8. Python多线程的实际应用

import threading
from time import sleep, ctime
class ThreadFunc:
def __init__(self, name):
self.name = name
def loop(self, nloop, nsec):
print(f'Start loop {nloop} at {ctime()}')
sleep(nsec)
print(f'Done loop {nloop} at {ctime()}')
def main():
print(f'Starting at: {ctime()}')
t1 = threading.Thread(target=ThreadFunc().loop, args=("LOOP1", 4))
t2 = threading.Thread(target=ThreadFunc().loop, args=("LOOP2", 2))
t1.start()
t2.start()
t1.join()
t2.join()
print(f'ALL done at: {ctime()}')
if __name__ == "__main__":
main()

9. 线程共享与安全性

  • 共享资源的非安全性
import threadingsum = 0n = 1000000
def Add(): global sum, n for i in range(n): sum += 1
def Minu(): global sum, n for i in range(n): sum -= 1
t1 = threading.Thread(target=Add) t2 = threading.Thread(target=Minu)
t1.start() t2.start() t1.join() t2.join() print(sum)
  • 使用互斥锁
import threadingsum = 0n = 1000000
lock = threading.Lock()
def Add(): for i in range(n): lock.acquire() sum += 1 lock.release()
def Minu(): for i in range(n): lock.acquire() sum -= 1 lock.release()
t1 = threading.Thread(target=Add) t2 = threading.Thread(target=Minu)
t1.start() t2.start() t1.join() t2.join() print(sum)

10. 线程特殊情形:可重入锁

import threading
import time
class MyThread(threading.Thread):
def run():
global num time.sleep(1) if mutex.acquire(1):
num += 1 msg = self.name + ' set num to ' + str(num)
print(msg)
time.sleep(1)
mutex.acquire()
time.sleep(1)
mutex.release()
num = 0
num = 0
mutex = threading.RLock()
def testTh():
for i in range(5):
t = MyThread() t.start()

这篇文章详细介绍了Python多线程的实现与使用方法,包括线程与进程的区别、多线程的同步与共享问题、线程的高级特性(如互斥锁、可重入锁、信号量等),以及Python线程的实际应用场景。

上一篇:python进阶--协程
下一篇:22 python基础--Log日志

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年05月05日 08时14分32秒