zoukankan      html  css  js  c++  java
  • 锁与线程

    -------------------------------------------START-------------------------------------------

    1.同步锁(Lock):

      锁通常被用来实现共享资源的同步访问.为买一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其他线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁.

    1 import threading
    2 
    3 R=threading.Lock()
    4 
    5 R.acquire()
    6 '''
    7 对公共数据的操作
    8 '''
    9 R.release()

    2.死锁与递归锁:

      所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.

      在Python中为了支持在同一线程中多次请求同一资源,Python提供了可重入锁RLock.这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require.直到一个线程所有的acquire都被release,其他线程才能获得资源.

    3.Event对象:

      在初始情况下,Event对象中的信号标志被设置为假.如果有线程等待一个Event对象,而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真.

    1 event.isSet():返回event的状态值;
    2 
    3 event.wait():如果 event.isSet()==False将阻塞线程;
    4 
    5 event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
    6 
    7 event.clear():恢复event的状态值为False。
     1 import threading
     2 import time
     3 import logging
     4 
     5 logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s) %(message)s',)
     6 
     7 def worker(event):
     8     logging.debug('okkkkkkkkkkkkkk------')
     9     while not event.isSet():   #默认 FALSE
    10         logging.debug('loading..............')
    11         event.wait()
    12     logging.debug(' coollllllllllllllllllllllllll[%s]', time.ctime())
    13     time.sleep(3)
    14 
    15 def main():
    16     readis_ready = threading.Event()
    17     t1 = threading.Thread(target=worker, args=(readis_ready,), name='t1')
    18     t1.start()
    19 
    20     t2 = threading.Thread(target=worker, args=(readis_ready,), name='t2')
    21     t2.start()
    22 
    23     logging.debug('-------------Me-is-a-fengexian---------')
    24     time.sleep(6) # simulate the check progress
    25     readis_ready.set()          #将event状态设置为TRUE
    26 
    27 if __name__=="__main__":
    28     main()

    4.Semaphore(信号量):

      Semaphore管理一个内置的计数器,

      每当调用acquire()时内置计数器-1;

      调用release()时内置计数器+1;

      计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release().

     1 import threading,time
     2 
     3 semaphore=threading.Semaphore(100)
     4 def fun():
     5     if semaphore.acquire():
     6         print(threading.current_thread().getName(),'get semaphore')
     7         time.sleep(2)
     8         semaphore.release()
     9 for i in range(1000):
    10     t1=threading.Thread(target=fun)
    11     t1.start()

    5.协程:

      1.yield与协程:

     1 import time
     2 
     3 """
     4 传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
     5 如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高。
     6 """
     7 # 注意到consumer函数是一个generator(生成器):
     8 # 任何包含yield关键字的函数都会自动成为生成器(generator)对象
     9 
    10 def consumer():
    11     r = ''
    12     while True:
    13         # 3、consumer通过yield拿到消息,处理,又通过yield把结果传回;
    14         #    yield指令具有return关键字的作用。然后函数的堆栈会自动冻结(freeze)在这一行。
    15         #    当函数调用者的下一次利用next()或generator.send()或for-in来再次调用该函数时,
    16         #    就会从yield代码的下一行开始,继续执行,再返回下一次迭代结果。通过这种方式,迭代器可以实现无限序列和惰性求值。
    17         n = yield r
    18         if not n:
    19             return
    20         print('[CONSUMER] ←← Consuming %s...' % n)
    21         time.sleep(1)
    22         r = '200 OK'
    23 def produce(c):
    24     # 1、首先调用c.next()启动生成器
    25     next(c)
    26     n = 0
    27     while n < 5:
    28         n = n + 1
    29         print('[PRODUCER] →→ Producing %s...' % n)
    30         # 2、然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
    31         cr = c.send(n)
    32         # 4、produce拿到consumer处理的结果,继续生产下一条消息;
    33         print('[PRODUCER] Consumer return: %s' % cr)
    34     # 5、produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
    35     c.close()
    36 if __name__=='__main__':
    37     # 6、整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
    38     c = consumer()
    39     produce(c)
    40     
    41     
    42 '''
    43 result:
    44 
    45 [PRODUCER] →→ Producing 1...
    46 [CONSUMER] ←← Consuming 1...
    47 [PRODUCER] Consumer return: 200 OK
    48 [PRODUCER] →→ Producing 2...
    49 [CONSUMER] ←← Consuming 2...
    50 [PRODUCER] Consumer return: 200 OK
    51 [PRODUCER] →→ Producing 3...
    52 [CONSUMER] ←← Consuming 3...
    53 [PRODUCER] Consumer return: 200 OK
    54 [PRODUCER] →→ Producing 4...
    55 [CONSUMER] ←← Consuming 4...
    56 [PRODUCER] Consumer return: 200 OK
    57 [PRODUCER] →→ Producing 5...
    58 [CONSUMER] ←← Consuming 5...
    59 [PRODUCER] Consumer return: 200 OK
    60 '''
    View Code

      2.greenlet

      greenlet机制主要思想:生成器函数或者协程函数中的yield语句挂起函数的执行,直到少受使用next()或send()操作进行恢复为止,可以使用一个调度器循环在一组生成器函数之间协作多个任务,greentle是Python中实现我们所谓的"Coroutine(协程)"的一个基础库.

     1 from greenlet import greenlet
     2  
     3 def test1():
     4     print (12)
     5     gr2.switch()
     6     print (34)
     7     gr2.switch()
     8  
     9 def test2():
    10     print (56)
    11     gr1.switch()
    12     print (78)
    13  
    14 gr1 = greenlet(test1)
    15 gr2 = greenlet(test2)
    16 gr1.switch()

      greenlet提供了一个在libev事件循环顶部的高级别并发API.

      gevent特点:

        <1> 基于libev的快速事件循环,Linux上面的是epoll机制

        <2> 基于greenlet的轻量级执行单元

        <3> API复用了Python标准库里的内容

        <4> 支持SSL的协作式sockets

        <5> 可通过线程池或c-ares实现DNS查询

        <6> 通过monkey patching功能来使得第三方模块变成协作式

    PS:协程:
        1.由于单线程,不能再切换!
        2.不再有任何锁的概念   


    -----------------------------------------2017-05-09----------------------------------------
    --------------------------------------------END--------------------------------------------

  • 相关阅读:
    Atcoder 1975 Iroha and Haiku
    训练指南 string easy
    心态回归
    Mysql问题处理
    Mysql-从库只读设置
    Redis5-集群搭建实验
    安装python3并新建python3的虚拟环境
    docker-部署zabbix4
    pt工具-mysql慢日志分析&优化
    Ansible:playbook-nagios
  • 原文地址:https://www.cnblogs.com/gz369521/p/6831433.html
Copyright © 2011-2022 走看看