python3多线程-线程同步

发布时间 2023-04-15 09:44:34作者: 挖洞404

1、介绍
多线程同时访问和操作同一资源,可能会造成异常。
解决办法是对资源进行限制,同一时间只允许一个线程进行访问和操作。
这里的资源,一般是指方法、函数或者代码块。即由多行代码组成,在逻辑上属于不可切分的操作。

2、线程同步
使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间

3、Lock类
(1)类

class Lock:
    def __init__(self) -> None:

(2)初始化

lock = threading.Lock()

(3)方法

# 上锁,对python系统资源独占,当该锁释放,其他线程才可以竞争
lock.acquire()
# 释放
lock.release()
# 判断是否上锁
def locked(self) -> bool
``

4、使用示例
如果不是考虑效率,而是为了并发的效果。一般,会搭配time.sleep函数,使每个线程在结束核心任务后,进行等待状态,让其他线程竞争执行。
如果存在多个线程使用同一资源,需要对各线程中涉及到该资源的代码进行上锁和释放处理,线程等待需要写在释放后才有预期的效果。
```python
import threading
import time

lock = threading.Lock()


def run():
    arr = []
    t = threading.Thread(target=a, args=["zs", 10, arr])
    t1 = threading.Thread(target=p, args=[arr])
    t1.start()
    t.start()

    t.join()
    t1.join()


# 输出结果数组
def p(result: list):
    while True:
        lock.acquire()
        print(len(result))
        lock.release()
        time.sleep(4)


def a(name, count, result: list):
    for i in range(count):
        lock.acquire()
        print("正在添加", name + ":" + str(i))
        result.append(name + ":" + str(i))
        lock.release()
        time.sleep(3)


run()

5、使用示例2
lock锁的使用:
线程内部,只有对共享的资源操作代码进行上锁和释放锁才有意义,对非共享的资源操作代码上锁是无意义的,反而降低了多线程的效率
不同线程间,只有使用的同一个锁对象,才会实现对某共享资源的同步操作。
各线程内执行到调用lock对象的acquire()方法时,判断锁是否被释放状态。如果是释放状态,则上锁,并继续执行。如果是锁定状态,则休眠至其他线程将锁打开。

import threading
import time


class stu:
    # 同步有效,交替执行
    lock = threading.Lock()

    def __init__(self, name):
        self.name = name
        self.id = 0
        # 同步无效,各自执行,混乱
        # self.lock = threading.Lock()

    def p(self, delay):
        while self.id < 30:
            self.lock.acquire()
            print(self.name, self.id)
            self.id = self.id + 1
            time.sleep(delay)
            self.lock.release()


stu1 = stu("a")
t1 = threading.Thread(target=stu1.p, args=[2.5])
t1.start()
stu2 = stu("b")
t2 = threading.Thread(target=stu2.p, args=[2.5])
t2.start()