天天看点

Python Day Eleven

目录:

一、线程

    1.线程基本操作 

        1.创建线程的方式

        2.线程锁

        3.信号量以及事件

        4.条件以及定时器

    2.队列的使用

        1.队列的使用

        2.生产者消费者模型

    3.自定义线程池

二、进程   

    1.进程基本操作

        1.创建进程

        2.进程锁

    2.进程池

三、协程

   1.greenlet

    2.gevent

四、缓存    

    1.python操作memcache

    2.python操作redis

  1.线程基本操作

      1.创建线程的方式

<code>#创建线程方法一(最常见)</code>

<code>import</code> <code>threading</code>

<code>def</code> <code>f1(args):</code>

<code>    </code><code>print</code><code>(args)</code>

<code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>f1,args</code><code>=</code><code>(</code><code>123</code><code>,))</code>

<code>t.start()   </code><code>#线程开启,等待cpu调用</code>

<code>'''</code>

<code>t.run() 方法:</code>

<code>    </code><code>当cpu调度的时候,就执行Thread里边的run方法</code>

<code>    </code><code>t.run() #是由cpu替我们调度执行的</code>

<code>#创建线程方法二 (通过创建类创建线程) (自定义方式)</code>

<code>class</code> <code>MyThread(threading.Thread):</code>

<code>    </code><code>def</code> <code>__init__(</code><code>self</code><code>,func,args): </code><code>#定义init,就不执行父类的方法了,执行自己的</code>

<code>        </code><code>self</code><code>.func </code><code>=</code> <code>func</code>

<code>        </code><code>self</code><code>.args </code><code>=</code> <code>args</code>

<code>        </code><code>super</code><code>(MyThread,</code><code>self</code><code>).__init__()</code>

<code>    </code><code>def</code> <code>run(</code><code>self</code><code>):</code>

<code>        </code><code>self</code><code>.func(</code><code>self</code><code>.args)</code>

<code>def</code> <code>f2(arg):</code>

<code>    </code><code>print</code><code>(arg)</code>

<code>obj </code><code>=</code> <code>MyThread(f2,</code><code>123</code><code>)            </code><code>#func = f2  args=123</code>

<code>obj.start()</code>

      2.线程锁(同时只允许一个线程进入取值。)

<code>线程锁分类:</code>

<code>    </code><code>1.</code>

<code>        </code><code>l.acquire()</code>

<code>        </code><code>l.release()</code>

<code>        </code><code>lock </code><code>=</code> <code>threading.Lock()     </code><code>#只能锁一次</code>

<code>    </code><code>2.</code>

<code>        </code><code>lock </code><code>=</code> <code>threadingRLock()    </code><code>#可以递归锁,可以锁多层,可以嵌套。 (常用)</code>

<code>例子:</code>

<code>当有一个数字</code><code>10</code><code>,如果同时</code><code>10</code><code>个线程去减</code><code>1</code><code>,</code>

<code>那么就会产生脏数据,输出结果都输出为</code><code>0</code><code>。</code>

<code>#例1</code>

<code>import</code> <code>time</code>

<code>NUM </code><code>=</code> <code>10</code>

<code>def</code> <code>func(l):</code>

<code>    </code><code>global</code> <code>NUM</code>

<code>    </code><code>NUM </code><code>-</code><code>=</code> <code>1</code>

<code>    </code><code>time.sleep(</code><code>2</code><code>)           </code><code>#会产生脏数据,造成输出都是0</code>

<code>    </code><code>print</code><code>(NUM)</code>

<code>lock </code><code>=</code> <code>threading.Lock()     </code><code>#只能锁一次</code>

<code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>10</code><code>):</code>

<code>    </code><code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>func,args</code><code>=</code><code>(lock,))</code>

<code>    </code><code>t.start()</code>

<code>#解决此问题就是加锁,同时只允许一个线程进入取值。;(单层锁)</code>

<code>#例2</code>

<code>    </code><code>l.acquire()             </code><code>#上锁 使同一时刻只有一个进程使用</code>

<code>    </code><code>l.release()             </code><code>#开锁</code>

<code>    </code> 

<code>#例3 多层锁</code>

<code>    </code><code>#上锁               #使同一时刻只有一个进程使用</code>

<code>    </code><code>l.acquire()</code>

<code>    </code><code>l.acquire()     </code><code>#多层锁</code>

<code>    </code><code>time.sleep(</code><code>2</code><code>)       </code><code>#会产生脏数据,造成输出都是0</code>

<code>    </code><code>l.release()     </code><code>#多层锁</code>

<code>    </code><code>l.release()     </code><code>#开锁</code>

<code>#lock = threading.Lock()     #只能锁一次</code>

<code>lock </code><code>=</code> <code>threading.RLock()    </code><code>#可以递归锁,可以锁多层,可以嵌套。</code>

      3.信号量以及事件

<code>信号量(semaphore)(同时允许一定数量的线程更改数据)</code>

<code>#例1 信号量(semaphore)(同时允许一定数量的线程更改数据)</code>

<code>def</code> <code>func(i,l):</code>

<code>    </code><code>#上锁             #使同一时刻只有一个进程使用</code>

<code>    </code><code>lock.acquire()       </code><code>#一次放5个出去</code>

<code>    </code><code>print</code><code>(NUM,i)</code>

<code>    </code><code>#开锁</code>

<code>    </code><code>lock.release()</code>

<code>lock </code><code>=</code> <code>threading.BoundedSemaphore(</code><code>5</code><code>)</code>

<code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>30</code><code>):</code>

<code>    </code><code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>func,args</code><code>=</code><code>(i,lock,))</code>

<code>#例2 事件(event)(事件用于主线程控制其他线程的执行,相当于红绿灯。主要有三个方法:set、wait、clear)</code>

<code>#批量将所有线程挡住,改一个标识,全部放走</code>

<code>#内部就是维护了一个状态,默认是False,改成True就能走了 。</code>

<code>#输出结果顺序不一样,是因为线程调度事件不一样</code>

<code>def</code> <code>func(i,e):</code>

<code>    </code><code>print</code><code>(i)</code>

<code>    </code><code>e.wait()        </code><code>#表示它在这等待;检测是什么灯,如果是红灯就停;</code>

<code>    </code><code>print</code><code>(i</code><code>+</code><code>100</code><code>)</code>

<code>event </code><code>=</code> <code>threading.Event()</code>

<code>    </code><code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>func,args</code><code>=</code><code>(i,event,))</code>

<code>#==========</code>

<code>event.clear()       </code><code>#主动设置成红灯就是False,默认是False</code>

<code>inp </code><code>=</code> <code>input</code><code>(</code><code>"&gt;&gt;"</code><code>)</code>

<code>if</code> <code>inp </code><code>=</code><code>=</code> <code>"1"</code><code>:     </code><code>#当输入1的时候就继续</code>

<code>    </code><code>event.</code><code>set</code><code>()     </code><code>#把上边的红灯设置成绿灯,将Flag设置为True</code>

      4.条件以及定时器

<code>条件Condition (使得线程等待,只有满足某条件时,才释放n个线程)</code>

<code>#例1: 当输入数字等于几时,那么久释放几个线程过去。</code>

<code>def</code> <code>run(n):</code>

<code>    </code><code>con.acquire()       </code><code>#配合下边wait使用</code>

<code>    </code><code>con.wait()          </code><code>#在这里等着了</code>

<code>    </code><code>print</code><code>(</code><code>"run the thread: %s"</code> <code>%</code><code>n)</code>

<code>    </code><code>con.release()</code>

<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>'__main__'</code><code>:</code>

<code>    </code><code>con </code><code>=</code> <code>threading.Condition()     </code><code>#创建条件</code>

<code>    </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>10</code><code>):</code>

<code>        </code><code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>run, args</code><code>=</code><code>(i,))</code>

<code>        </code><code>t.start()</code>

<code>    </code><code>while</code> <code>True</code><code>:</code>

<code>        </code><code>inp </code><code>=</code> <code>input</code><code>(</code><code>'&gt;&gt;&gt;'</code><code>)</code>

<code>        </code><code>if</code> <code>inp </code><code>=</code><code>=</code> <code>'q'</code><code>:</code>

<code>            </code><code>break</code>

<code>        </code><code>#以下三行是固定用法</code>

<code>        </code><code>con.acquire()</code>

<code>        </code><code>con.notify(</code><code>int</code><code>(inp))</code>

<code>        </code><code>con.release()</code>

<code>        </code> 

<code>#当条件满足之后,出去一个,再满足,再出去一个</code>

<code>#例2     当满足条件,输入true,那么就i+100 ,再输入true 下个数再加100</code>

<code>def</code> <code>condition():</code>

<code>    </code><code>ret </code><code>=</code> <code>False</code>

<code>    </code><code>r </code><code>=</code> <code>input</code><code>(</code><code>"&gt;&gt;&gt;&gt;"</code><code>)</code>

<code>    </code><code>if</code> <code>r </code><code>=</code><code>=</code> <code>'true'</code><code>:</code>

<code>        </code><code>ret </code><code>=</code> <code>True</code>

<code>    </code><code>else</code><code>:</code>

<code>        </code><code>ret </code><code>=</code> <code>False</code>

<code>    </code><code>return</code> <code>ret</code>

<code>def</code> <code>func(i,con):</code>

<code>    </code><code>con.acquire()   </code><code>#配合下边wait使用</code>

<code>    </code><code>con.wait_for(condition)  </code><code>#在这里等着了</code>

<code>c </code><code>=</code> <code>threading.Condition()</code>

<code>    </code><code>t </code><code>=</code> <code>threading.Thread(target</code><code>=</code><code>func,args</code><code>=</code><code>(i,c,))</code>

<code>#定时器 Timer   (定时器,指定n秒后执行某操作)</code>

<code>#例3</code>

<code>#1秒钟之后执行某函数</code>

<code>#应用到写客户端、监控的时候。</code>

<code>from</code> <code>threading </code><code>import</code> <code>Timer</code>

<code>def</code> <code>hello():</code>

<code>    </code><code>print</code><code>(</code><code>"hello world"</code><code>)</code>

<code>t </code><code>=</code> <code>Timer(</code><code>1</code><code>,hello)    </code><code>#1秒钟之后执行</code>

<code>t.start()</code>

  2.队列的使用(Python中队列是线程间最常用的交换数据的形式)

<code>1.queue</code><code>队列</code>

<code>    </code><code>基本特点:</code>

<code>        </code><code>先进先出</code>

<code>    </code><code>方法:</code>

<code>        </code><code>put         放数据,是否阻塞,阻塞时的超时时间</code>

<code>        </code><code>get         取数据,默认阻塞,是否阻塞,阻塞时的超时时间</code>

<code>        </code><code>q.empty     检查队列是否为空,为空返回</code><code>True</code><code>,否则</code><code>False</code>

<code>        </code><code>q.full      判对是否满了</code>

<code>        </code><code>q.qsize     队列里边有几个元素;当前真实个数</code>

<code>        </code><code>q.maxsize   元素最大支持的个数</code>

<code>        </code><code>q.join      如果队列任务没有完成,还在等待。</code>

<code>        </code><code>q.taskdone  每一次取完数据的时候执行q.task_done(),告诉我执行完了,系统做一个计数。表示我取完数据了</code>

<code>        </code><code>join,task_done 阻塞进程,当队列中任务执行完毕之后,不再阻塞。</code>

<code>2.</code><code>其他队列:</code>

<code>    </code><code>1</code><code>、后进先出</code>

<code>        </code><code>queue.LifoQueue</code>

<code>    </code><code>2</code><code>、优先级队列 (放数据的时候加上权重值;内容包括:数据</code><code>+</code><code>权重)</code>

<code>        </code><code>queue.PriorityQueue</code>

<code>    </code><code>3</code><code>、双向队列    (两边存、两边取)</code>

<code>        </code><code>queue.deque</code>

<code>import</code> <code>queue        </code><code>#导入队列模块</code>

<code>q </code><code>=</code> <code>queue.Queue(</code><code>10</code><code>)          </code><code>#创建一个队列;参数10代表最多接收10个数据。放不进去就等着或者报错</code>

<code>q.put(</code><code>11</code><code>,timeout</code><code>=</code><code>2</code><code>)          </code><code>#放数据;timeout=2 代表等待2秒,如果还没有位置就报错;有位置就加进去</code>

<code>q.put(</code><code>22</code><code>,block</code><code>=</code><code>False</code><code>)       </code><code>#默认block是阻塞等待,只要没有位置就等待;如果改成True,就不等待,直接报错</code>

<code>q.put(</code><code>33</code><code>)</code>

<code>print</code><code>(q.qsize())             </code><code>#显示当前多少数据</code>

<code>print</code><code>(q.get(block</code><code>=</code><code>False</code><code>))   </code><code>#取数据;默认是阻塞,默认情况下没有数据的时候就一直等待,</code>

<code>print</code><code>(q.empty())             </code><code>#检查队列是否为空,为空返回True,否则False</code>

<code>#输出</code>

<code>    </code><code>3</code>

<code>    </code><code>11</code>

<code>    </code><code>False</code>

<code>q </code><code>=</code> <code>queue.Queue(</code><code>5</code><code>)</code>

<code>q.put(</code><code>44</code><code>)</code>

<code>print</code><code>(q.get())</code>

<code>print</code><code>(q.task_done())</code>

<code>#输出:</code>

<code>    </code><code>33</code>

<code>    </code><code>None</code>

<code>    </code><code>44</code>

<code>#每一次取完数据的时候执行q.task_done(),告诉我执行完了,系统做一个计数。表示我取完数据了</code>

<code>#q.join()    #如果队列任务没有完成,还在等待。</code>

<code>#queue.LifoQueue    特点:后进先出</code>

<code>q </code><code>=</code> <code>queue.LifoQueue()</code>

<code>q.put(</code><code>123</code><code>)</code>

<code>q.put(</code><code>456</code><code>)</code>

<code>print</code><code>(q.get())      </code><code>#456是后进去的,先取出来</code>

<code>    </code><code>456</code>

<code>#queue.PriorityQueue    特点:优先级队列</code>

<code>q </code><code>=</code> <code>queue.PriorityQueue()</code>

<code>q.put((</code><code>1</code><code>,</code><code>'aaa'</code><code>))</code>

<code>q.put((</code><code>2</code><code>,</code><code>'bbb'</code><code>))</code>

<code>print</code><code>(q.get())      </code><code>#按照优先级取数据,如果优先级相同,谁先放,先取谁</code>

<code>    </code><code>(</code><code>1</code><code>, </code><code>'aaa'</code><code>)</code>

<code>#queue.deque    特点:双向队列(两边都可以取数据,都可以放数据)</code>

<code>q </code><code>=</code><code>queue.deque()</code>

<code>q.append(</code><code>123</code><code>)</code>

<code>q.append(</code><code>456</code><code>)</code>

<code>q.appendleft(</code><code>333</code><code>)   </code><code>#左边放数据</code>

<code>print</code><code>(q.pop())      </code><code>#取数据,默认取最右边的</code>

<code>print</code><code>(q.popleft())  </code><code>#左边取数据</code>

<code>    </code><code>333</code>

  3.自定义线程池

<code>&lt;br&gt;</code>

     本文转自506554897 51CTO博客,原文链接:http://blog.51cto.com/506554897/1843549,如需转载请自行联系原作者