我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python3中最常用的5种线程锁的应用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python3中最常用的5种线程锁的应用

本篇内容主要讲解“Python3中最常用的5种线程锁的应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python3中最常用的5种线程锁的应用”吧!

目录
  • 前言

  • 线程安全

  • 锁的作用

  • Lock() 同步锁

    • 基本介绍

    • 使用方式

    • 死锁现象

    • with语句

  • RLock() 递归锁

    • 基本介绍

    • 使用方式

    • with语句

  • Condition() 条件锁

    • 基本介绍

    • 使用方式

    • with语句

  • Event() 事件锁

    • 基本介绍

    • 使用方式

  • Semaphore() 信号量锁

    • 使用方式

    • with语句

  • 锁关系浅析

    • 基本练习题

      • 条件锁的应用

      • 事件锁的应用

    前言

    本章节将继续围绕threading模块讲解,基本上是纯理论偏多。

    对于日常开发者来讲很少会使用到本章节的内容,但是对框架作者等是必备知识,同时也是高频的面试常见问题。

    官方文档

    线程安全

    线程安全是多线程或多进程编程中的一个概念,在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。

    线程安全的问题最主要还是由线程切换导致的,比如一个房间(进程)中有10颗糖(资源),除此之外还有3个小人(1个主线程、2个子线程),当小人A吃了3颗糖后被系统强制进行休息时他认为还剩下7颗糖,而当小人B工作后又吃掉了3颗糖,那么当小人A重新上岗时会认为糖还剩下7颗,但是实际上只有4颗了。

    上述例子中线程A和线程B的数据不同步,这就是线程安全问题,它可能导致非常严重的意外情况发生,我们按下面这个示例来进行说明。

    下面有一个数值num初始值为0,我们开启2条线程:

    • 线程1对num进行一千万次+1的操作

    • 线程2对num进行一千万次-1的操作

    结果可能会令人咋舌,num最后并不是我们所想象的结果0:

    import threadingnum = 0def add():    global num    for i in range(10_000_000):        num += 1def sub():    global num    for i in range(10_000_000):        num -= 1if __name__ == "__main__":    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)# 结果三次采集# num result : 669214# num result : -1849179# num result : -525674

    上面这就是一个非常好的案例,想要解决这个问题就必须通过锁来保障线程切换的时机。

    需要我们值得留意的是,在Python基本数据类型中list、tuple、dict本身就是属于线程安全的,所以如果有多个线程对这3种容器做操作时,我们不必考虑线程安全问题。

    锁的作用

    锁是Python提供给我们能够自行操控线程切换的一种手段,使用锁可以让线程的切换变的有序。

    一旦线程的切换变的有序后,各个线程之间对数据的访问、修改就变的可控,所以若要保证线程安全,就必须使用锁。

    threading模块中提供了5种最常见的锁,下面是按照功能进行划分:

    • 同步锁:lock(一次只能放行一个)

    • 递归锁:rlock(一次只能放行一个)

    • 条件锁:condition(一次可以放行任意个)

    • 事件锁:event(一次全部放行)

    • 信号量锁:semaphore(一次可以放行特定个)

    Lock() 同步锁

    基本介绍

    Lock锁的称呼有很多,如:

    1. 同步锁

    2. 互斥锁

    它们是什么意思呢?如下所示:

    1. 互斥指的是某一资源同一时刻仅能有一个访问者对其进行访问,具有唯一性和排他性,但是互斥无法限制访问者对资源的访问顺序,即访问是无序的

    2. 同步是指在互斥的基础上(大多数情况),通过其他机制实现访问者对资源的有序访问

    3. 同步其实已经实现了互斥,是互斥的一种更为复杂的实现,因为它在互斥的基础上实现了有序访问的特点

    下面是threading模块与同步锁提供的相关方法:

    方法描述
    threading.Lock()返回一个同步锁对象
    lockObject.acquire(blocking=True, timeout=1)上锁,当一个线程在执行被上锁代码块时,将不允许切换到其他线程运行,默认锁失效时间为1秒
    lockObject.release()解锁,当一个线程在执行未被上锁代码块时,将允许系统根据策略自行切换到其他线程中运行
    lockObject.locaked()判断该锁对象是否处于上锁状态,返回一个布尔值

    使用方式

    同步锁一次只能放行一个线程,一个被加锁的线程在运行时不会将执行权交出去,只有当该线程被解锁时才会将执行权通过系统调度交由其他线程。

    如下所示,使用同步锁解决最上面的问题:

    import threadingnum = 0def add():    lock.acquire()    global num    for i in range(10_000_000):        num += 1    lock.release()def sub():    lock.acquire()    global num    for i in range(10_000_000):        num -= 1    lock.release()if __name__ == "__main__":    lock = threading.Lock()    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)# 结果三次采集# num result : 0# num result : 0# num result : 0

    这样这个代码就完全变成了串行的状态,对于这种计算密集型I/O业务来说,还不如直接使用串行化单线程执行来得快,所以这个例子仅作为一个示例,不能概述锁真正的用途。

    死锁现象

    对于同步锁来说,一次acquire()必须对应一次release(),不能出现连续重复使用多次acquire()后再重复使用多次release()的操作,这样会引起死锁造成程序的阻塞,完全不动了,如下所示:

    import threadingnum = 0def add():    lock.acquire()  # 上锁    lock.acquire()  # 死锁    # 不执行    global num    for i in range(10_000_000):        num += 1    lock.release()    lock.release()def sub():    lock.acquire()  # 上锁    lock.acquire()  # 死锁    # 不执行    global num    for i in range(10_000_000):        num -= 1    lock.release()    lock.release()if __name__ == "__main__":    lock = threading.Lock()    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)

    with语句

    由于threading.Lock()对象中实现了__enter__()与__exit__()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作:

    import threadingnum = 0def add():    with lock:        # 自动加锁        global num        for i in range(10_000_000):            num += 1        # 自动解锁def sub():    with lock:        # 自动加锁        global num        for i in range(10_000_000):            num -= 1        # 自动解锁if __name__ == "__main__":    lock = threading.Lock()    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)    # 结果三次采集# num result : 0# num result : 0# num result : 0

    RLock() 递归锁

    基本介绍

    递归锁是同步锁的一个升级版本,在同步锁的基础上可以做到连续重复使用多次acquire()后再重复使用多次release()的操作,但是一定要注意加锁次数和解锁次数必须一致,否则也将引发死锁现象。

    下面是threading模块与递归锁提供的相关方法:

    方法描述
    threading.RLock()返回一个递归锁对象
    lockObject.acquire(blocking=True, timeout=1)上锁,当一个线程在执行被上锁代码块时,将不允许切换到其他线程运行,默认锁失效时间为1秒
    lockObject.release()解锁,当一个线程在执行未被上锁代码块时,将允许系统根据策略自行切换到其他线程中运行
    lockObject.locaked()判断该锁对象是否处于上锁状态,返回一个布尔值

    使用方式

    以下是递归锁的简单使用,下面这段操作如果使用同步锁则会发生死锁现象,但是递归锁不会:

    import threadingnum = 0def add():    lock.acquire()    lock.acquire()    global num    for i in range(10_000_000):        num += 1    lock.release()    lock.release()def sub():    lock.acquire()    lock.acquire()    global num    for i in range(10_000_000):        num -= 1    lock.release()    lock.release()if __name__ == "__main__":    lock = threading.RLock()    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)# 结果三次采集# num result : 0# num result : 0# num result : 0

    with语句

    由于threading.RLock()对象中实现了__enter__()与__exit__()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作:

    import threadingnum = 0def add():    with lock:        # 自动加锁        global num        for i in range(10_000_000):            num += 1        # 自动解锁def sub():    with lock:        # 自动加锁        global num        for i in range(10_000_000):            num -= 1        # 自动解锁if __name__ == "__main__":    lock = threading.RLock()    subThread01 = threading.Thread(target=add)    subThread02 = threading.Thread(target=sub)    subThread01.start()    subThread02.start()    subThread01.join()    subThread02.join()    print("num result : %s" % num)# 结果三次采集# num result : 0# num result : 0# num result : 0

    Condition() 条件锁

    基本介绍

    条件锁是在递归锁的基础上增加了能够暂停线程运行的功能。并且我们可以使用wait()与notify()来控制线程执行的个数。

    注意:条件锁可以自由设定一次放行几个线程。

    下面是threading模块与条件锁提供的相关方法:

    方法描述
    threading.Condition()返回一个条件锁对象
    lockObject.acquire(blocking=True, timeout=1)上锁,当一个线程在执行被上锁代码块时,将不允许切换到其他线程运行,默认锁失效时间为1秒
    lockObject.release()解锁,当一个线程在执行未被上锁代码块时,将允许系统根据策略自行切换到其他线程中运行
    lockObject.wait(timeout=None)将当前线程设置为“等待”状态,只有该线程接到“通知”或者超时时间到期之后才会继续运行,在“等待”状态下的线程将允许系统根据策略自行切换到其他线程中运行
    lockObject.wait_for(predicate, timeout=None)将当前线程设置为“等待”状态,只有该线程的predicate返回一个True或者超时时间到期之后才会继续运行,在“等待”状态下的线程将允许系统根据策略自行切换到其他线程中运行。注意:predicate参数应当传入一个可调用对象,且返回结果为bool类型
    lockObject.notify(n=1)通知一个当前状态为“等待”的线程继续运行,也可以通过参数n通知多个
    lockObject.notify_all()通知所有当前状态为“等待”的线程继续运行

    使用方式

    下面这个案例会启动10个子线程,并且会立即将10个子线程设置为等待状态。

    然后我们可以发送一个或者多个通知,来恢复被等待的子线程继续运行:

    import threadingcurrentRunThreadNumber = 0maxSubThreadNumber = 10def task():    global currentRunThreadNumber    thName = threading.currentThread().name    condLock.acquire()  # 上锁    print("start and wait run thread : %s" % thName)    condLock.wait()  # 暂停线程运行、等待唤醒    currentRunThreadNumber += 1    print("carry on run thread : %s" % thName)    condLock.release()  # 解锁if __name__ == "__main__":    condLock = threading.Condition()    for i in range(maxSubThreadNumber):        subThreadIns = threading.Thread(target=task)        subThreadIns.start()    while currentRunThreadNumber < maxSubThreadNumber:        notifyNumber = int(            input("Please enter the number of threads that need to be notified to run:"))        condLock.acquire()        condLock.notify(notifyNumber)  # 放行        condLock.release()    print("main thread run end")    # 先启动10个子线程,然后这些子线程会全部变为等待状态# start and wait run thread : Thread-1# start and wait run thread : Thread-2# start and wait run thread : Thread-3# start and wait run thread : Thread-4# start and wait run thread : Thread-5# start and wait run thread : Thread-6# start and wait run thread : Thread-7# start and wait run thread : Thread-8# start and wait run thread : Thread-9# start and wait run thread : Thread-10# 批量发送通知,放行特定数量的子线程继续运行# Please enter the number of threads that need to be notified to run:5  # 放行5个# carry on run thread : Thread-4# carry on run thread : Thread-3# carry on run thread : Thread-1# carry on run thread : Thread-2# carry on run thread : Thread-5# Please enter the number of threads that need to be notified to run:5  # 放行5个# carry on run thread : Thread-8# carry on run thread : Thread-10# carry on run thread : Thread-6# carry on run thread : Thread-9# carry on run thread : Thread-7# Please enter the number of threads that need to be notified to run:1# main thread run end

    with语句

    由于threading.Condition()对象中实现了__enter__()与__exit__()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作:

    import threadingcurrentRunThreadNumber = 0maxSubThreadNumber = 10def task():    global currentRunThreadNumber    thName = threading.currentThread().name    with condLock:        print("start and wait run thread : %s" % thName)        condLock.wait()  # 暂停线程运行、等待唤醒        currentRunThreadNumber += 1        print("carry on run thread : %s" % thName)if __name__ == "__main__":    condLock = threading.Condition()    for i in range(maxSubThreadNumber):        subThreadIns = threading.Thread(target=task)        subThreadIns.start()    while currentRunThreadNumber < maxSubThreadNumber:        notifyNumber = int(            input("Please enter the number of threads that need to be notified to run:"))        with condLock:            condLock.notify(notifyNumber)  # 放行    print("main thread run end")

    Event() 事件锁

    基本介绍

    事件锁是基于条件锁来做的,它与条件锁的区别在于一次只能放行全部,不能放行任意个数量的子线程继续运行。

    我们可以将事件锁看为红绿灯,当红灯时所有子线程都暂停运行,并进入“等待”状态,当绿灯时所有子线程都恢复“运行”。

    下面是threading模块与事件锁提供的相关方法:

    方法描述
    threading.Event()返回一个事件锁对象
    lockObject.clear()将事件锁设为红灯状态,即所有线程暂停运行
    lockObject.is_set()用来判断当前事件锁状态,红灯为False,绿灯为True
    lockObject.set()将事件锁设为绿灯状态,即所有线程恢复运行
    lockObject.wait(timeout=None)将当前线程设置为“等待”状态,只有该线程接到“绿灯通知”或者超时时间到期之后才会继续运行,在“等待”状态下的线程将允许系统根据策略自行切换到其他线程中运行

    使用方式

    事件锁不能利用with语句来进行使用,只能按照常规方式。

    如下所示,我们来模拟线程和红绿灯的操作,红灯停,绿灯行:

    import threadingmaxSubThreadNumber = 3def task():    thName = threading.currentThread().name    print("start and wait run thread : %s" % thName)    eventLock.wait()  # 暂停运行,等待绿灯    print("green light, %s carry on run" % thName)    print("red light, %s stop run" % thName)    eventLock.wait()  # 暂停运行,等待绿灯    print("green light, %s carry on run" % thName)    print("sub thread %s run end" % thName)if __name__ == "__main__":    eventLock = threading.Event()    for i in range(maxSubThreadNumber):        subThreadIns = threading.Thread(target=task)        subThreadIns.start()    eventLock.set()  # 设置为绿灯    eventLock.clear()  # 设置为红灯    eventLock.set()  # 设置为绿灯# start and wait run thread : Thread-1# start and wait run thread : Thread-2# start and wait run thread : Thread-3# green light, Thread-1 carry on run# red light, Thread-1 stop run# green light, Thread-1 carry on run# sub thread Thread-1 run end# green light, Thread-3 carry on run# red light, Thread-3 stop run# green light, Thread-3 carry on run# sub thread Thread-3 run end# green light, Thread-2 carry on run# red light, Thread-2 stop run# green light, Thread-2 carry on run# sub thread Thread-2 run end

    Semaphore() 信号量锁

    基本介绍

    信号量锁也是根据条件锁来做的,它与条件锁和事件锁的区别如下:

    • 条件锁:一次可以放行任意个处于“等待”状态的线程

    • 事件锁:一次可以放行全部的处于“等待”状态的线程

    • 信号量锁:通过规定,成批的放行特定个处于“上锁”状态的线程

    下面是threading模块与信号量锁提供的相关方法:

    方法描述
    threading.Semaphore()返回一个信号量锁对象
    lockObject.acquire(blocking=True, timeout=1)上锁,当一个线程在执行被上锁代码块时,将不允许切换到其他线程运行,默认锁失效时间为1秒
    lockObject.release()解锁,当一个线程在执行未被上锁代码块时,将允许系统根据策略自行切换到其他线程中运行

    使用方式

    以下是使用示例,你可以将它当做一段限宽的路段,每次只能放行相同数量的线程:

    import threadingimport timemaxSubThreadNumber = 6def task():    thName = threading.currentThread().name    semaLock.acquire()    print("run sub thread %s" % thName)    time.sleep(3)    semaLock.release()if __name__ == "__main__":    # 每次只能放行2个    semaLock = threading.Semaphore(2)    for i in range(maxSubThreadNumber):        subThreadIns = threading.Thread(target=task)        subThreadIns.start()# run sub thread Thread-1# run sub thread Thread-2# run sub thread Thread-3# run sub thread Thread-4# run sub thread Thread-6# run sub thread Thread-5

    with语句

    由于threading.Semaphore()对象中实现了__enter__()与__exit__()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作:

    import threadingimport timemaxSubThreadNumber = 6def task():    thName = threading.currentThread().name    with semaLock:        print("run sub thread %s" % thName)        time.sleep(3)if __name__ == "__main__":    semaLock = threading.Semaphore(2)    for i in range(maxSubThreadNumber):        subThreadIns = threading.Thread(target=task)        subThreadIns.start()

    锁关系浅析

    上面5种锁可以说都是基于同步锁来做的,这些你都可以从源码中找到答案。

    首先来看RLock递归锁,递归锁的实现非常简单,它的内部会维护着一个计数器,当计数器不为0的时候该线程不能被I/O操作和时间轮询机制切换。但是当计数器为0的时候便不会如此了:

    def __init__(self):    self._block = _allocate_lock()    self._owner = None    self._count = 0  # 计数器

    而Condition条件锁的内部其实是有两把锁的,一把底层锁(同步锁)一把高级锁(递归锁)。

    低层锁的解锁方式有两种,使用wait()方法会暂时解开底层锁同时加上一把高级锁,只有当接收到别的线程里的notfiy()后才会解开高级锁和重新上锁低层锁,也就是说条件锁底层是根据同步锁和递归锁的不断切换来进行实现的:

    def __init__(self, lock=None):    if lock is None:        lock = RLock()  # 可以看到条件锁的内部是基于递归锁,而递归锁又是基于同步锁来做的    self._lock = lock    self.acquire = lock.acquire    self.release = lock.release    try:        self._release_save = lock._release_save    except AttributeError:        pass    try:        self._acquire_restore = lock._acquire_restore    except AttributeError:        pass    try:        self._is_owned = lock._is_owned    except AttributeError:        pass    self._waiters = _deque()

    Event事件锁内部是基于条件锁来做的:

    class Event:    def __init__(self):        self._cond = Condition(Lock())  # 实例化出了一个条件锁。        self._flag = False    def _reset_internal_locks(self):        # private!  called by Thread._reset_internal_locks by _after_fork()        self._cond.__init__(Lock())    def is_set(self):        """Return true if and only if the internal flag is true."""        return self._flag    isSet = is_set

    Semaphore信号量锁内部也是基于条件锁来做的:

    class Semaphore:    def __init__(self, value=1):        if value < 0:            raise ValueError("semaphore initial value must be >= 0")        self._cond = Condition(Lock()) # 可以看到,这里是实例化出了一个条件锁        self._value = value

    基本练习题

    条件锁的应用

    需求:一个空列表,两个线程轮番往里面加值(一个加偶数,一个加奇数),最终让该列表中的值为 1 - 100 ,且是有序排列的。

    import threadinglst = []def even():    """加偶数"""    with condLock:        for i in range(2, 101, 2):            # 判断当前列表的长度处于2是否能处尽            # 如果能处尽则代表需要添加奇数            # 否则就添加偶数            if len(lst) % 2 != 0:                # 添偶数                lst.append(i)      # 先添加值                condLock.notify()  # 告诉另一个线程,你可以加奇数了,但是这里不会立即交出执行权                condLock.wait()    # 交出执行权,并等待另一个线程通知加偶数            else:                # 添奇数                condLock.wait()  # 交出执行权,等待另一个线程通知加偶数                lst.append(i)                    condLock.notify()        condLock.notify()def odd():    """加奇数"""    with condLock:        for i in range(1, 101, 2):            if len(lst) % 2 == 0:                lst.append(i)                condLock.notify()                condLock.wait()        condLock.notify()if __name__ == "__main__":    condLock = threading.Condition()    addEvenTask = threading.Thread(target=even)    addOddTask = threading.Thread(target=odd)    addEvenTask.start()    addOddTask.start()    addEvenTask.join()    addOddTask.join()    print(lst)

    事件锁的应用

    有2个任务线程来扮演李白和杜甫,如何让他们一人一句进行对答?文本如下:

    杜甫:老李啊,来喝酒!

    李白:老杜啊,不喝了我喝不下了!

    杜甫:老李啊,再来一壶?

    杜甫:...老李?

    李白:呼呼呼...睡着了..

    代码如下:

    import threadingdef libai():    event.wait()      print("李白:老杜啊,不喝了我喝不下了!")    event.set()    event.clear()    event.wait()    print("李白:呼呼呼...睡着了..")def dufu():    print("杜甫:老李啊,来喝酒!")    event.set()      event.clear()    event.wait()    print("杜甫:老李啊,再来一壶?")    print("杜甫:...老李?")    event.set()if __name__ == '__main__':    event = threading.Event()    t1 = threading.Thread(target=libai)    t2 = threading.Thread(target=dufu)    t1.start()    t2.start()    t1.join()    t2.join()

    到此,相信大家对“Python3中最常用的5种线程锁的应用”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Python3中最常用的5种线程锁的应用

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Python3中最常用的5种线程锁的应用

    本篇内容主要讲解“Python3中最常用的5种线程锁的应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python3中最常用的5种线程锁的应用”吧!目录前言线程安全锁的作用Lock() 同步锁
    2023-06-20

    推荐,用于AI开发的5种最佳编程语言

    AI(人工智能)为应用程序开发人员开创了一个全新的可能性。通过利用机器学习或深度学习,您可以生成更好的用户配置文件,个性化设置和建议,或者整合更智能的搜索,语音界面或智能帮助,或者改进您的应用程序的任何其他方式。你甚至可以构建看,听,并作出反应的应用程序。我们一起看看。
    推荐,用于AI开发的5种最佳编程语言
    2024-04-23

    认识双绞线最常使用的两种连接方法

      双绞线是一种综合布线工程中最常用的传输介质,是由两根具有绝缘保护层的铜导线组成的。把两根绝缘的铜导线按一定密度互相绞在一起,每一根导线在传输中辐射出来的电波会被另一根线上发出的电波抵消,有效降低信号干扰的程度。现在就跟着小编共同来学习一下:认识双绞线最常使用的两种连接方法。  相信大家在网吧网络搭建过程里面,都会使
    认识双绞线最常使用的两种连接方法
    2024-04-18

    python3爬虫中多线程的使用示例

    这篇文章主要介绍了python3爬虫中多线程的使用示例,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。本文教程操作环境:windows7系统、Python 3.9.1,DELL
    2023-06-14

    C++ 多线程编程中线程池的应用

    c++++ 多线程编程中使用线程池的好处包括:1)减少线程创建次数;2)负载均衡;3)避免资源争用。例如,通过使用线程池将图像转换任务分配给线程池,可以提高文件转换应用程序的转换速度。C++ 多线程编程中线程池的应用在现代 C++ 应用程
    C++ 多线程编程中线程池的应用
    2024-05-14

    Java多线程编程中的锁有什么用

    这篇文章主要讲解了“Java多线程编程中的锁有什么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java多线程编程中的锁有什么用”吧!阅读目录一、尽量不要锁住方法二、缩小同步代码块,只锁数
    2023-06-17

    Qt中的线程怎么应用

    今天小编给大家分享一下Qt中的线程怎么应用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、多线程操作UI界面的示例下面,是
    2023-07-05

    C#多线程中的互斥锁Mutex怎么用

    本篇内容主要讲解“C#多线程中的互斥锁Mutex怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#多线程中的互斥锁Mutex怎么用”吧!一、简介Mutex的突出特点是可以跨应用程序域边界对
    2023-06-30

    python中的多线程锁lock=threading.Lock()如何使用

    这篇文章主要介绍“python中的多线程锁lock=threading.Lock()如何使用”,在日常操作中,相信很多人在python中的多线程锁lock=threading.Lock()如何使用问题上存在疑惑,小编查阅了各式资料,整理出简
    2023-07-02

    举例讲解Python编程中对线程锁的使用

    锁 python的内置数据结构比如列表和字典等是线程安全的,但是简单数据类型比如整数和浮点数则不是线程安全的,要这些简单数据类型的通过操作,就需要使用锁。#!/usr/bin/env python3 # coding=utf-8import
    2022-06-04

    关于多线程常用方法以及对锁的控制(详解)

    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不同访问共享数据。注意该方法要捕获异常比如有两个线程同时执行(没有S
    2023-05-31

    Android 中三种启用线程的方法总结

    在多线程编程这块,我们经常要使用Handler(处理),Thread(线程)和Runnable这三个类,那么他们之间的关系你是否弄清楚了呢? 首先说明Android的CPU分配的最小单元是线程,Handler一般是在某个线程里创建的,因而H
    2022-06-06

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录