zoukankan      html  css  js  c++  java
  • day 42(锁 + )

    锁:

      经典面试题

    # # GIL
    # # 锁
    import time
    from threading import Thread,Lock
    def func(lock):
        global n
        # lock.acquire()
        temp = n            #在这里睡了一秒,所以程序会进入就绪状态,下面又是同步运行,但是上面可以异步运行(global n 和 temp = n) 
        # time 会让程序重新进入就绪状态,每一次执行子线程,都会改变global n,而不是真正的n
        time.sleep(0.1)
        n = temp -1
        # lock.release()
    
    n = 100
    t_lst = []
    lock = Lock()   #
    for i in range(100):
        t = Thread(target=func,args=(lock,))
        t.start()
        t_lst.append(t)
    for t in t_lst:t.join()   #让所有线程变成同步的
    print(n)
    # 数据是不隔离
    
    # from threading import Thread
    #
    # def func():
    #     global n
    #     temple = n
    #     n = temple - 1
    #
    # n = 100
    # for i in range(100):
    #     t = Thread(target = func)
    #     t.start()
    
    # print(n)

    互斥锁:

    from threading import Thread,Lock

    lock = Lock()

    lock.acquire()

    lock.acquire()

    lock.acquire()

    lock.release()

    # 卡住了(阻塞了)

    科学家吃面问题:

    # from threading import Lock
    #
    # lock= Lock() # 在同一个线程中
    # # 能够被一个锁的多个acquire阻塞住了
    # # 这种锁就叫做互斥锁
    # lock.acquire()
    # lock.acquire()

    # 科学家吃面问题
    # 要完成一件事情 需要两个必要因素
    # 要想吃到面 叉子 面
    # 资源的互相抢占的问题 —— 死锁
    # import time
    # from threading import Thread,Lock
    # def eat1(noodle_lock,fork_lock,name):
    # noodle_lock.acquire()
    # print('%s抢到了面'%name)
    # fork_lock.acquire()
    # print('%s抢到了叉子'%name)
    # print('%s正在吃面'%name)
    # fork_lock.release()
    # print('%s归还了叉子' % name)
    # noodle_lock.release()
    # print('%s归还了面' % name)
    #
    # def eat2(noodle_lock,fork_lock,name):
    # fork_lock.acquire()
    # print('%s抢到了叉子' % name)
    # time.sleep(0.5)
    # noodle_lock.acquire()
    # print('%s抢到了面'%name)
    # print('%s正在吃面'%name)
    # noodle_lock.release()
    # print('%s归还了面' % name)
    # fork_lock.release()
    # print('%s归还了叉子' % name)
    #
    # if __name__ == '__main__':
    # noodle_lock = Lock()
    # fork_lock = Lock()
    # Thread(target=eat1,args=(noodle_lock,fork_lock,'yuan')).start()
    # Thread(target=eat2,args=(noodle_lock,fork_lock,'egon')).start()
    # Thread(target=eat1,args=(noodle_lock,fork_lock,'nezha')).start()
    # Thread(target=eat2,args=(noodle_lock,fork_lock,'alex')).start()

    # 递归锁
    # from threading import Thread,RLock
    # # 在同一个线程中对同一个锁多次acquire不会产生阻塞
    # # 递归锁
    # def func(rlock,flag):
    # rlock.acquire()
    # print(flag*10)
    # rlock.acquire()
    # print(flag * 10)
    # rlock.acquire()
    # print(flag * 10)
    # rlock.acquire()
    # print(flag * 10)
    # rlock.release()
    # rlock.release()
    # rlock.release()
    # rlock.release()
    # rlock = RLock()
    # Thread(target=func,args=(rlock,'*')).start()
    # Thread(target=func,args=(rlock,'-')).start()



    import time
    from threading import Thread,RLock
    def eat1(noodle_lock,fork_lock,name):
    noodle_lock.acquire()
    print('%s抢到了面'%name)
    fork_lock.acquire()
    print('%s抢到了叉子'%name)
    print('%s正在吃面'%name)
    fork_lock.release()
    print('%s归还了叉子' % name)
    noodle_lock.release()
    print('%s归还了面' % name)

    def eat2(noodle_lock,fork_lock,name):
    fork_lock.acquire()
    print('%s抢到了叉子' % name)
    time.sleep(0.5)
    noodle_lock.acquire()
    print('%s抢到了面'%name)
    print('%s正在吃面'%name)
    noodle_lock.release()
    print('%s归还了面' % name)
    fork_lock.release()
    print('%s归还了叉子' % name)

    if __name__ == '__main__':
    fork_lock = noodle_lock = RLock()
    Thread(target=eat1,args=(noodle_lock,fork_lock,'yuan')).start()
    Thread(target=eat2,args=(noodle_lock,fork_lock,'egon')).start()
    Thread(target=eat1,args=(noodle_lock,fork_lock,'nezha')).start()
    Thread(target=eat2,args=(noodle_lock,fork_lock,'alex')).start()

    # 有超过一个资源需要锁的时候 —— 递归锁
    # 递归锁的应用场景
    # 互斥锁和递归锁的区别



    import time
    import random
    from threading import Event,Thread

    # wait()
    # set clear isset

    # 连接数据库
    def connect_db(e):
    count = 1
    while count < 4:      #第一次进入默认是False
    print('尝试第%s次检测连接'%count)
    e.wait(0.5)
    # 如果不传参数会一直等到事件为True为止
    # 如果传参数 传一个时间参数
    count += 1
    if e.is_set():
    print('连接成功')
    break
    else:
    print('连接失败')

    def check_conn(e):
    '''检测数据库是否可以连接'''
    time.sleep(random.randint(1,2))
    e.set()                        此题:如果小于1.5 会把状态False 改为 True ,否则会执行else:结束程序

    e = Event()
    Thread(target=check_conn,args=(e,)).start()
    Thread(target=connect_db,args=(e,)).start()

    # 你要做一件事情 是有前提的
    # 你就先去处理前提的问题 —— 前提处理好了 把状态设置成True
    # 来控制即将要做的事情可以开始

    条件和定时器:

     from threading import Condition,Thread
    # # acquire release
    # # notify -- wait的行为
    # # 10线程 wait
    # # notify(1)
    # def func(i,con):
    # con.acquire()
    # con.wait()
    # print(i*'*')
    # con.release()
    #
    # con = Condition()
    # for i in range(10):
    # Thread(target=func,args=(i,con)).start()
    # while True:
    # n = int(input('>>>'))
    # con.acquire()
    # con.notify()
    # con.release()
    #
    # con.acquire()
    # con.notify_all()
    # con.release()

    # semaphore 允许统一是个n个线程执行这段代码
    # event 有一个内部的事件来控制wait的行为
    #控制的是所有的线程
    # condition 有一个内部的条件来控制wait的行为
    #可以逐个或者分批次的控制线程的走向

    from threading import Timer
    def func():
    print('*'*20)

    t = Timer(5,func) # 要开启一个线程,等到5秒钟之后才开启并且执行
    t.start()
    print('-'*10)
    print('^'*10)




    队列:

    import queue

    q = queue.LifoQueue()
    q = queue.Queue()
    q.put('first')
    q.put((1,2))
    q.put([1,2])
    q.put({'k':'v'})
    q.put(lambda :1)
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())

    q = queue.PriorityQueue()
    q.put((1,'a')) #数字越小优先级越高
    q.put((20,'z'))
    q.put((20,'b'))
    print(q.get())
    print(q.get())
    print(q.get())




    线程池:

    # import time
    # from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    # def func(i):
    # print(i*'*')
    # time.sleep(1)
    # return i**2
    #
    # def callb(arg):
    # print(arg.result()*'-')
    #
    # if __name__ == '__main__':
    # # thread_pool = ThreadPoolExecutor(5)
    # thread_pool = ThreadPoolExecutor(5)
    # # ret_lst = []
    # for i in range(10):
    # thread_pool.submit(func,i).add_done_callback(callb) # 相当于apply_async
    # # ret = thread_pool.submit(func,i).add_done_callback(callable) # 相当于apply_async
    # # ret_lst.append(ret)
    # thread_pool.shutdown() # close+join
    # # for ret in ret_lst:
    # # print(ret.result())
    # print('wahaha')
    # # 回调函数

    # 进程池
    # 线程池


    # 当内存不需要共享,且高计算的时候 用进程
    # 当内存需要共享,且高IO的时候 用线程
    # 当并发很大的时候
    # 多进程 : 多个任务 —— 进程池 :cpu个数、cpu个数+1
    # 多线程 :多个任务 —— 线程池 :cpu个数*5
    # 4C : 4个、5个进程 —— 20条线程/进程 : 80-100个任务
    # 50000

    # import time
    # from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
    #
    # def fun(i):
    # print(i*'*')
    # time.sleep(1)
    # return i**2
    #
    # def callc(args):
    # print(args.result()*'-')
    #
    #
    # thread_pool = ThreadPoolExecutor(5)
    # for i in range(10):
    # ret = thread_pool.submit(fun,i).add_done_callback(callc)
    # # thread_pool.map(fun,range(10))
    # thread_pool.shutdown()
    # print('wahh')




    import time
    from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor

    def fun(i):
    print('*'*i)
    time.sleep(1)
    return i**2

    def callc(args):
    print(args.result() * '-')

    thread_pool = ThreadPoolExecutor(5)
    for i in range(10):
    ret = thread_pool.submit(fun,i).add_done_callback(callc)

    thread_pool.shutdown()

    print('主线程')














  • 相关阅读:
    github上十二款最著名的Android播放器开源项目
    ReactiveX/RxJava文档中文版
    腾讯开源的Android UI框架——QMUI Android
    android EventBus的简单使用
    android EventBus的简单使用
    MVP实战心得—封装Retrofit2.0+RxAndroid+RxBus
    动态合并Repeater控件数据列
    动态合并GridView数据行DataRow的列
    找出1至10范围奇数
    判断某元素是否在Array中
  • 原文地址:https://www.cnblogs.com/zsdbk/p/9048187.html
Copyright © 2011-2022 走看看