1.多线程
Python3中使用_thread模块或者threading模块实现多线程,threading模块相较于_thread模块对线程的操作更加的丰富,而且threading模块本身也是相当于对thread模块的进一步封装而成,thread模块有的功能threading模块也都有,所以涉及到多线程的操作,推荐使用threading模块。
实例:
# -*- coding: utf-8 -*-
# @Time : 2022/4/14 17:42
# @File : threaddemo.py
# @Software : PyCharm
import threading
from time import sleep
# 定义一个测试函数
def test(i):
print('test', i)
sleep(1)
print('test', i)
sleep(1)
if __name__ == '__main__':
# 这里有个关键的地方是target的内容是要执行的函数名,不是函数,就是说不要把后面的括号还有参数直接写进来,参数用args来传递
t1 = threading.Thread(target=test, args=('线程1',))
# 再加入一个进程,当然对象也可以是其他你想要的函数
t2 = threading.Thread(target=test, args=('线程2',))
t1.start() # 启动Thread对象
t2.start()
运行结果:
test 线程1
test 线程2
test 线程2
test 线程1
2.线程同步 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,造成数据的不一致。
实例:
import threading
cur = 0
def add():
global cur
for i in range(1000000):
cur += 1
def desc():
global cur
for i in range(1000000):
cur-= 1
for i in range(1000):
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(cur)
以上程序因为+=和-= 操作不能保证原子性,因此运行多次也不能保证cur的结果每次都是0. 与Java类似python也可以通过锁机制,实现线程同步。创建一个锁就是通过threading.Lock()来实现的。
改写如下:
# -*- coding: utf-8 -*-
# @Time : 2022/4/17 11:34
# @File : threaddemo2.py
# @Software : PyCharm
import threading
from threading import Lock, RLock
cur = 0
lock = Lock()
def add():
global cur
for i in range(100000):
lock.acquire()
try:
cur += 1
finally:
lock.release()
def desc():
global cur
for i in range(100000):
lock.acquire()
try:
cur -= 1
finally:
lock.release()
for i in range(1000):
thread1 = threading.Thread(target=add)
thread2 = threading.Thread(target=desc)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(cur)
Lock也有一些缺点: