zoukankan      html  css  js  c++  java
  • 进程与线程2

    有了GIL还是会出现数据不安全,所以还是要用锁

    import time

    from threading import Thread,Lock

    n = 100

    def func(lock):

      global n

      with lock:

        tmp = n-1

        n = tmp

    l = []

    lock = Lock()

    for i in range(100):

      t = Thread(target = func,args = (lock,))

      t.smxtart()

      l.append(t)

    for t in l:t.join()

    print(n)

    dis模块(判断数据是否安全)

    import dis

    n = 1

    def func():

      n = 100

      n -= 1

    dis.dis(func)

    死锁现象

      死锁不是时刻发生的,有偶然的情况,每一个线程中不止一把锁,并且套着使用

    解决死锁的方案

      如果某一件事情需要两个资源同时出现,那么不应该将两个资源通过两把锁控制,而是看做是一个资源,用一把锁控制,先临时解决,然后找到死锁原因,再去修改(科学家吃面条)(递归锁也能解决死锁现象)。

    出现死锁现象

    # def eat1(name):
    # noodle_lock.acquire()
    # print('%s拿到面条了'%name)
    # fork_lock.acquire()
    # print('%s拿到叉子了'%name)
    # print('%s开始吃面'%name)
    # time.sleep(0.2)
    # fork_lock.release()
    # print('%s放下叉子了' % name)
    # noodle_lock.release()
    # print('%s放下面了' % name)
    #
    # def eat2(name):
    # fork_lock.acquire()
    # print('%s拿到叉子了' % name)
    # noodle_lock.acquire()
    # print('%s拿到面条了' % name)
    # print('%s开始吃面' % name)
    # time.sleep(0.2)
    # noodle_lock.release()
    # print('%s放下面了' % name)
    # fork_lock.release()
    # print('%s放下叉子了' % name)
    #
    # Thread(target=eat1,args=('alex',)).start()
    # Thread(target=eat2,args=('wusir',)).start()
    # Thread(target=eat1,args=('太白',)).start()
    # Thread(target=eat2,args=('宝元',)).start()
    解决死锁
    # lock = Lock()
    # def eat1(name):
    # lock.acquire()
    # print('%s拿到面条了'%name)
    # print('%s拿到叉子了'%name)
    # print('%s开始吃面'%name)
    # time.sleep(0.2)
    # lock.release()
    # print('%s放下叉子了' % name)
    # print('%s放下面了' % name)
    #
    # def eat2(name):
    # lock.acquire()
    # print('%s拿到叉子了' % name)
    # print('%s拿到面条了' % name)
    # print('%s开始吃面' % name)
    # time.sleep(0.2)
    # lock.release()
    # print('%s放下面了' % name)
    # print('%s放下叉子了' % name)
    #
    # Thread(target=eat1,args=('alex',)).start()
    # Thread(target=eat2,args=('wusir',)).start()
    # Thread(target=eat1,args=('太白',)).start()
    # Thread(target=eat2,args=('宝元',)).start()



    递归锁(RLock)
    在同一个线程中可以无限次acquire,但是要想在其他线程中也acquire,必须先在自己线程中添加和acquire次数相同的release
    import time
    noodle_lock = fork_lock = RLock()
    def eat1(name):
      noodle_lock.acquire()
      print('%s拿到了面条'%name)
      frok_lock.aquire()
      print('%s拿到了叉子'%name)
      print('%s开始吃面'%name)
      time.sleep(0.2)
      fork_lock.release()
      print('%s放下叉子'%name)
      noodle_lock.release()
      print('%s放下面条'%name)
    def eat2(name):
      fork_lock.acquire()
      print('%s拿到了叉子'%name)
      noodle_lock.acquire()
      print('%s拿到了面条'%name)
      print('%s开始吃面'%name)
      time.sleep(0.2)
      fork_lock.release()
      print('%s放下叉子'%name)
      noodle_lock.release()
      print('%s放下面条'%name)
    Thread(target = eat1,args = ('alex',)).start()
    Thread(target = eat1,args = ('wusir',)).start()
    Thread(target = eat1,args = ('taibai',)).start()
    Thread(target = eat1,args = ('baiyuan',)).start()

    线程 信号量(Semaphore)
    import time
    from threading import Semaphore,Thread

    def func(name,sem):
    sem.acquire()
    print(name,'start')
    time.sleep(1)
    print(name,'stop')
    sem.release()

    sem = Semaphore(5)
    for i in range(20):
    Thread(target=func,args=(i,sem)).start()
    进程池
      有1000个任务,一个进程池中有5个进程,所有的1000个任务会多次利用这五个进程来完成任务
    信号量
      有1000个任务,有1000个线程、进程所有的1000个任务由于信号量的控制,只能5个5个的执行




    线程事件 (Event)
      wait()阻塞 事件内部标识为True就停止阻塞
    控制标识
      set #True
      clear  #False
      is_set #判断是不是True


    连接数据库(用事件)
    import time
    import random
    from threading import Thread,Event
    def connect_sql(e):
    count = 0
    while count < 3:
    e.wait(0.5)
    if e.is_set():
    print('连接数据库成功')
    break
    else:
    print('数据库未连接成功')
    count += 1
    F
    def test(e):
    time.sleep(random.randint(0,3))
    e.set()

    e = Event()
    Thread(target=test,args=(e,)).start()
    Thread(target=connect_sql,args=(e,)).start()



    线程条件()
      wait 阻塞
      notify(n) 给信号
      假如现在有20个线程,所有的线程都在wait这里阻塞,nptify(n)n传了多少,那么wait这边就能收获得到多少个解除阻塞的通知

    import threading

    def run(n):
    con.acquire()
    con.wait()
    print("run the thread: %s" % n)
    con.release()

    if __name__ == '__main__':

    con = threading.Condition()
    for i in range(10):
    t = threading.Thread(target=run, args=(i,))
    t.start()

    while True:
    inp = input('>>>')
    if inp == 'q':
    break
    con.acquire()
    con.notify(int(inp))
    con.release()
    print('****')

    设置某个条件
    如果满足这个条件 就可以释放线程
    监控测试我的网速
    20000个任务
    测试我的网速 /系统资源
    发现系统资源有空闲,我就放行一部分任务




    线程定时器(Timer)
    from threading import Timer

    def func():
    print('执行我啦')

    t = Timer(3,func)      #参数3为3秒,就是等待3秒在执行子线程
                # 现在这个时间点我不想让它执行,而是预估一下大概多久之后它执行比较合适
    t.start()
    print('主线程的逻辑')




    线程队列(Queue) #先进先出
    q = queue.Queue()
    线程栈(LifoQueue)  #先进后出
    lfq = queue.LifoQueue()   # 栈
    lfq.put(1)
    lfq.put(2)
    lfq.put(3)
    print(lfq.get())
    print(lfq.get())
    print(lfq.get())

    优先级队列(PriorityQueue) #根据第一个值的大小来排定优先级(ascii码越小,优先级越高)
    q = queue.PriorityQueue()
    q.put((2,'a'))
    q.put((1,'c'))
    q.put((1,'b'))
    print(q.get())

    线程池
    concurrent.futures




      
      

  • 相关阅读:
    中译英6
    中译英5
    中译英4
    B5
    BEC listen and translation exercise 37
    BEC listen and translation exercise 36
    中译英2
    PyQt(Python+Qt)学习随笔:Designer中ItemViews类部件的frameShadow属性
    第15.16节 PyQt(Python+Qt)入门学习:PyQt中的信号(signal)和槽(slot)机制以及Designer中的使用
    PyQt(Python+Qt)学习随笔:Designer中ItemViews类部件frameShape属性
  • 原文地址:https://www.cnblogs.com/hahahu/p/10111571.html
Copyright © 2011-2022 走看看