博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
锁与线程
阅读量:6196 次
发布时间:2019-06-21

本文共 4917 字,大约阅读时间需要 16 分钟。

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

1.同步锁(Lock):

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

1 import threading2 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():   #默认 FALSE10         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 progress25     readis_ready.set()          #将event状态设置为TRUE26 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 r18         if not n:19             return20         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 = 027     while n < 5:28         n = n + 129         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 OK48 [PRODUCER] →→ Producing 2...49 [CONSUMER] ←← Consuming 2...50 [PRODUCER] Consumer return: 200 OK51 [PRODUCER] →→ Producing 3...52 [CONSUMER] ←← Consuming 3...53 [PRODUCER] Consumer return: 200 OK54 [PRODUCER] →→ Producing 4...55 [CONSUMER] ←← Consuming 4...56 [PRODUCER] Consumer return: 200 OK57 [PRODUCER] →→ Producing 5...58 [CONSUMER] ←← Consuming 5...59 [PRODUCER] Consumer return: 200 OK60 '''
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--------------------------------------------

转载于:https://www.cnblogs.com/gz369521/p/6831433.html

你可能感兴趣的文章
varnish缓存三:VCL配置示例
查看>>
POJ 3635 Full Tank?
查看>>
easyui datagrid 点击表头的事件
查看>>
Hadoop学习总结(1)——大数据以及Hadoop相关概念介绍
查看>>
Lync 2013创建持久聊天室失败
查看>>
部署SCCM2007 R3(4)---安装SCCM2007R3
查看>>
重磅预告 | 今晚直播:MyCat的坑如何在分布式中间件DBLE上改善
查看>>
mysql资源集合
查看>>
Eclipse下开发RMI
查看>>
ajax跨域请求原理及解决方案分析
查看>>
关闭sql server 2005远程连接
查看>>
lighttpd+php+mysql) discuz安装
查看>>
Dependency management (rebar 依赖库配置)
查看>>
iOS验证码
查看>>
2014年7月16日51CTO技术博客—我是IT界的奇葩
查看>>
<我的PHP生涯>-忆-PHP基础1-可变变量与引用赋值
查看>>
event.keycode值大全
查看>>
MyEclipse修改java字体大小及jsp字体大小
查看>>
Linux 配置Java开发环境
查看>>
Eclipse中最常用的快捷键
查看>>