zoukankan      html  css  js  c++  java
  • Python 之并发编程之线程中

    .线程锁lock(线程的数据安全)

    在数据量较大的时候,线程中的数据会被并发,所有数据会不同步,以至于数据会异常。

    下面还介绍了两种的上锁方法。

    例:

    from threading import Thread, Lock

    import time

    n = 0

    def func1(lock):

        global n

        # time.sleep(0.3)

    # print(11)

        for i in range(10000):

            # 正常上锁

            lock.acquire()

            print(n)

            n -= 1

            lock.release()

    def func2(lock):

        global n

        # time.sleep(0.3)

        # print(22)

        for i in range(10000):

            # with 自动上锁解锁

            with lock:

                print(n)

                n += 1

    if __name__ == "__main__":

        # 创建一个锁

        lock = Lock()

        lst = []

        for i in range(10):

            t1 = Thread(target=func1, args=(lock,))

            t2 = Thread(target=func2, args=(lock,))

            t1.start()

            t2.start()

            lst.append(t1)

            lst.append(t2)

        for i in lst:

            i.join()

        print("主线程执行语句结束")

        print(n) # n最后得0,如果没有加上锁的话,不会是0

    # 程序执行结束

    .线程的信号量

    例:效果是5个一打印,5个一打印

    from threading import Semaphore, Thread

    import time, random

    def func(i, sem):

        # with简写

        with sem:

            print(i)

            time.sleep(random.uniform(0.1, 1))

        """

        # 正常写法

        sem.acquire()

        print(i)

        time.sleep(random.uniform(0.1,1))

        sem.release()

        

        """

    if __name__ == "__main__":

        sem = Semaphore(5)  # 设置几个线程同时运行几个

        for i in range(50):

            Thread(target=func, args=(i, sem)).start()

    .线程的锁

    1.死锁

    :只有拿到筷子和面才能吃

    noodle_lock = Lock()

    chopsticks_lock = Lock()

    def eat1(name):

        noodle_lock.acquire()

        print("%s拿到面条" % (name))

        chopsticks_lock.acquire()

        print("%s拿到筷子" % (name))

        print("开始吃")

        time.sleep(0.7)

        chopsticks_lock.release()

        print("%s放下筷子" % (name))

        noodle_lock.release()

        print("%s放下面条" % (name))

    def eat2(name):

        chopsticks_lock.acquire()

        print("%s拿到筷子" % (name))

        noodle_lock.acquire()

        print("%s拿到面条" % (name))

        print("开始吃")

        time.sleep(0.6)

        noodle_lock.release()

        print("%s放下面条" % (name))

        chopsticks_lock.release()

        print("%s放下筷子" % (name))

    if __name__ == "__main__":

        name_list1 = ["one", "two"]

        name_list2 = ["three", "four"]

        for name in name_list1:

            Thread(target=eat1, args=(name,)).start()

        for name in name_list2:

            Thread(target=eat2, args=(name,)).start()

    # 双方都在等待,造成死锁的现象.

    2.递归锁RLock

    递归锁专门用来解决死锁现象

    临时用于快速解决服务器崩溃的异常现象,用递归锁应急

    解决应急问题的

    (1)基本用法

    from threading import Thread,RLock

    # 递归锁如果3,就对于释放3分锁,忽略上锁过程,进行解锁

    rlock = RLock()

    def func(name):

        rlock.acquire()

        print(name,1)

        rlock.acquire()

        print(name,2)

        rlock.acquire()

        print(name,3)

        rlock.release()

        rlock.release()

        rlock.release()

    lst = []

    for i in range(10):

        t1 = Thread(target=func,args=("name%s" % (i), ))

        t1.start()

        lst.append(t1)

    for i in lst:

        i.join()

    print("程序结束了")

    (2)用递归锁应急解决死锁现象

    # 用递归锁应急解决死锁现象

    noodle_lock = chopsticks_lock = RLock()

    def eat1(name):

        noodle_lock.acquire()

        print("%s拿到面条" % (name))

        chopsticks_lock.acquire()

        print("%s拿到筷子" % (name))

        print("开始吃")

        time.sleep(0.7)

        chopsticks_lock.release()

        print("%s放下筷子" % (name))

        noodle_lock.release()

        print("%s放下面条" % (name))

    def eat2(name):

        chopsticks_lock.acquire()

        print("%s拿到筷子" % (name))

        noodle_lock.acquire()

        print("%s拿到面条" % (name))

        print("开始吃")

        time.sleep(0.6)

        noodle_lock.release()

        print("%s放下面条" % (name))

        chopsticks_lock.release()

        print("%s放下筷子" % (name))

    if __name__ == "__main__":

        name_list1 = ["one", "two"]

        name_list2 = ["three", "four"]

        for name in name_list1:

            Thread(target=eat1, args=(name,)).start()

        for name in name_list2:

            Thread(target=eat2, args=(name,)).start()

    3.互斥锁

        从语法上来看,锁是可以互相嵌套的,但是不要使用

        上一次锁,就对应解开一把锁,形成互斥锁

        吃面条和拿筷子是同时的,上一次锁就够了,不要分别上锁

        尽量不要形成锁的嵌套,容易死锁

    例:   

    from threading import Thread,RLock

    mylock = Lock()

    def eat1(name):

        mylock.acquire()

        print("%s拿到面条" % (name))

        print("%s拿到筷子" % (name))

        print("开始吃")

        time.sleep(0.7)

        print("%s放下筷子" % (name))

        print("%s放下面条" % (name))

        mylock.release()

    def eat2(name):

        mylock.acquire()

        print("%s拿到筷子" % (name))

        print("%s拿到面条" % (name))

        print("开始吃")

        time.sleep(0.6)

        print("%s放下面条" % (name))

        print("%s放下筷子" % (name))

        mylock.release()

    if __name__ == "__main__":

        name_list1 = ["one", "two"]

        name_list2 = ["three", "four"]

        for name in name_list1:

            Thread(target=eat1, args=(name,)).start()

        for name in name_list2:

            Thread(target=eat2, args=(name,)).start()

  • 相关阅读:
    hbase-15-如何查看HFile
    Hbase-14-MemStore Flush的触发时机
    Hbase-13-MemStore
    【c++】C++中erase的用法
    Redis五种数据结构(转载)
    redis的三种集群方式 (转载)
    hbase和hive的差别是什么,各自适用在什么场景中?(转载)
    vue 数据已经更新了但是页面未更新
    uni-app配置跨域
    覆盖 web-view (uni-app)
  • 原文地址:https://www.cnblogs.com/hszstudypy/p/11222639.html
Copyright © 2011-2022 走看看