锁与线程

-------------------------------------------START-------------------------------------------并发

1.同步锁(Lock):socket

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

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

2.死锁与递归锁:函数

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

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

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(信号量):debug

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

  每当调用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         # 三、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     # 一、首先调用c.next()启动生成器
25     next(c)
26     n = 0
27     while n < 5:
28         n = n + 1
29         print('[PRODUCER] →→ Producing %s...' % n)
30         # 二、而后,一旦生产了东西,经过c.send(n)切换到consumer执行;
31         cr = c.send(n)
32         # 四、produce拿到consumer处理的结果,继续生产下一条消息;
33         print('[PRODUCER] Consumer return: %s' % cr)
34     # 五、produce决定不生产了,经过c.close()关闭consumer,整个过程结束。
35     c.close()
36 if __name__=='__main__':
37     # 六、整个流程无锁,由一个线程执行,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--------------------------------------------

相关文章
相关标签/搜索