D10——C语言基础学PYTHON

时间:2024-01-21 15:53:20

C语言基础学习PYTHON——基础学习D10

20180906内容纲要:

  1、协程 

    (1)yield

    (2)greenlet

    (3)gevent

    (4)gevent实现单线程下socket多并发

  2、简单爬虫

  3、select

  4、IO多路复用

  5、小结

  6、练习

 

1 协程

协程
又叫微线程,纤程。协程是一种用户态的轻量级线程。
协程有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文、和栈保存到其他地方,在切换回来的时候回复先前保存的寄存器上下文和栈。
协程能保存上一次调用时的状态。一个cpu支持上万个协程都不是问题,很适合用于高并发处理。
协程的本质就是单线程。无法利用多核资源。

实现协程主要有以下几种方式:

(1)yield

 1 #Author:ZhangKanghui
 2 
 3 
 4 def Producer():
 5     r = con1.__next__()
 6     r = con2.__next__()
 7     n = 0
 8     while n < 5:
 9         n += 1
10         con1.send(n)
11         con2.send(n)
12         print("\033[32;1m[Producer]\033[0m is making baozi %s"%n)
13 
14 def Consumer(name):
15     print("-->>start---")
16     while True:
17         new_balozi = yield
18         print("[%s] is eating baozi %s"%(name,new_balozi))
19         #time.sleep(1)
20 
21 if __name__ == '__main__':
22     con1 = Consumer("c1")       #函数中存在yield只是生成器,并没有真正生成,所以需要necxt
23     con2 = Consumer("c2")
24     p = Producer()
yield实现协程

通过这个例子协程到底是什么呢?

  1. 必须在只有一个单线程里实现并发
  2. 修改共享数据不需加锁
  3. 用户程序里自己保存多个控制流的上下文栈
  4. 一个协程遇到IO操作自动切换到其它协程

当然,还有其他实现方式。

(2)greenlet

greenlet是一个用C实现的协程模块。

 1 #Author:ZhangKanghui
 2 
 3 from greenlet import greenlet
 4 def func1():
 5     print(12)
 6     gr2.switch()
 7     print(34)
 8     gr2.switch()
 9 
10 def func2():
11     print(56)
12     gr1.switch()
13     print(78)
14 
15 gr1 = greenlet(func1)       #启动协程
16 gr2 = greenlet(func2)
17 gr1.switch()
greenlet实现协程

(3)gevent

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程。

在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。

Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

 1 #Author:ZhangKanghui
 2 
 3 import gevent
 4 
 5 def Foo():
 6     print("Running in Foo")
 7     gevent.sleep(2)
 8     print("Explicit context switch to Foo again")
 9 
10 def bar():
11     print("Explicit context to bar")
12     gevent.sleep(1)
13     print("Implicit context switch back to bar")
14 
15 def func():
16     print("running in func")
17     gevent.sleep(0)
18     print("running in func again")
19 gevent.joinall(
20     [gevent.spawn(Foo),
21      gevent.spawn(bar),
22      gevent.spawn(func)
23 ])
gevent实现协程

(4)gevent实现单线程下socket多并发

 1 #Author:ZhangKanghui
 2 
 3 import sys
 4 import socket
 5 import time
 6 import gevent
 7 from gevent import socket,monkey
 8 
 9 monkey.patch_all()
10 
11 def server(port):
12     s = socket.socket()
13     s.bind(('localhost',port))
14     s.listen(500)
15     while True:
16         cli,addr = s.accept()
17         gevent.spawn(handle_request,cli)
18 
19 def handle_request(conn):
20     try:
21         while True:
22             data = conn.recv(10214)
23             print("recv:",data)
24             conn.send(data)
25             if not data:
26                 conn.shutdown(socket.SHUT_WR)
27     except Exception as e:
28         print(e)
29     finally:
30         conn.close()
31 
32 if __name__ == '__main__':
33     server(8001)
gevnet_socket_server
 1 #Author:ZhangKanghui
 2 
 3 import socket
 4 
 5 HOST = 'localhost'
 6 PORT = 8001
 7 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 8 s.connect((HOST,PORT))
 9 while True:
10     msg = bytes(input(">>:"),encoding="utf-8")
11     s.sendall(msg)
12     data = s.recv(1024)
13 
14     #print("Received",repr(data))
15     print("Received",data)
16 
17 s.close()
gevent_socket_client

 

2 简单爬虫

网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常被称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本,已被广泛应用于互联网领域。搜索引擎使用网络爬虫抓取Web网页、文档甚至图片、音频、视频等资源,通过相应的索引技术组织这些信息,提供给搜索用户进行查询。网络爬虫也为中小站点的推广提供了有效的途径。

那么我们就简单来看看以下爬虫吧:

 1 #Author:ZhangKanghui
 2 
 3 from urllib import request
 4 
 5 def f(url):
 6     print("GET:%s"%url)
 7     resp = request.urlopen(url)
 8     data = resp.read()
 9     f = open("url.html",'wb')
10     f.write(data)
11     f.close()
12     print("%d bytes received from %s."%(len(data),url))
13 
14 f("https://www.cnblogs.com/zhangkanghui/p/9577714.html")
爬虫urblib
  1 <!DOCTYPE html>
  2 <html lang="zh-cn">
  3 <head>
  4 <meta charset="utf-8"/>
  5 <meta name="viewport" content="width=device-width, initial-scale=1" />
  6 <meta name="referrer" content="origin" />
  7 <title>D09——C语言基础学PYTHON - m1racle - 博客园</title>
  8 <meta property="og:description" content="C语言基础学习PYTHON——基础学习D09 20180903内容纲要: 线程、进程 1、paramiko 2、线程、进程初识 3、线程 (1)线程的调用方式 (2)join (3)线程锁、递归锁、信" />
  9 <link type="text/css" rel="stylesheet" href="/bundles/blog-common.css?v=D7Le-lOZiZVAXQkZQuNwdTWqjabXaVBE_2YAWzY_YZs1"/>
 10 <link id="MainCss" type="text/css" rel="stylesheet" href="/skins/red_autumnal_leaves/bundle-red_autumnal_leaves.css?v=EDEp2d1uMe8iyN6qDoW8MQgYb-JCFIeiYP0oX3XiiRM1"/>
 11 <link id="mobile-style" media="only screen and (max-width: 767px)" type="text/css" rel="stylesheet" href="/skins/red_autumnal_leaves/bundle-red_autumnal_leaves-mobile.css?v=d9LctKHRIQp9rreugMcQ1-UJuq_j1fo0GZXTXj8Bqrk1"/>
 12 <link title="RSS" type="application/rss+xml" rel="alternate" href="https://www.cnblogs.com/zhangkanghui/rss"/>
 13 <link title="RSD" type="application/rsd+xml" rel="EditURI" href="https://www.cnblogs.com/zhangkanghui/rsd.xml"/>
 14 <link type="application/wlwmanifest+xml" rel="wlwmanifest" href="https://www.cnblogs.com/zhangkanghui/wlwmanifest.xml"/>
 15 <script src="//common.cnblogs.com/scripts/jquery-2.2.0.min.js"></script>
 16 <script type="text/javascript">var currentBlogApp = 'zhangkanghui', cb_enable_mathjax=false;var isLogined=false;</script>
 17 <script src="/bundles/blog-common.js?v=yRkjgN2sBQkB4hX-wirHxPomeBT9sB5dawr6ob7KIvg1" type="text/javascript"></script>
 18 </head>
 19 <body>
 20 <a name="top"></a>
 21 
 22 <!--done-->
 23 <div id="home">
 24 <div id="header">
 25     <div id="blogTitle">
 26     <a id="lnkBlogLogo" href="https://www.cnblogs.com/zhangkanghui/"><img id="blogLogo" src="/Skins/custom/images/logo.gif" alt="返回主页" /></a>            
 27         
 28 <!--done-->
 29 <h1><a id="Header1_HeaderTitle" class="headermaintitle" href="https://www.cnblogs.com/zhangkanghui/">m1racle</a></h1>
 30 <h2></h2>
 31 
 32 
 33 
 34         
 35     </div><!--end: blogTitle 博客的标题和副标题 -->
 36     <div id="navigator">
 37         
 38 <ul id="navList">
 39 <li><a id="blog_nav_sitehome" class="menu" href="https://www.cnblogs.com/">博客园</a></li>
 40 <li><a id="blog_nav_myhome" class="menu" href="https://www.cnblogs.com/zhangkanghui/">首页</a></li>
 41 <li><a id="blog_nav_newpost" class="menu" rel="nofollow" href="https://i.cnblogs.com/EditPosts.aspx?opt=1">新随笔</a></li>
 42 <li><a id="blog_nav_contact" class="menu" rel="nofollow" href="https://msg.cnblogs.com/send/m1racle">联系</a></li>
 43 <li><a id="blog_nav_rss" class="menu" href="https://www.cnblogs.com/zhangkanghui/rss">订阅</a>
 44 <!--<a id="blog_nav_rss_image" class="aHeaderXML" href="https://www.cnblogs.com/zhangkanghui/rss"><img src="//www.cnblogs.com/images/xml.gif" alt="订阅" /></a>--></li>
 45 <li><a id="blog_nav_admin" class="menu" rel="nofollow" href="https://i.cnblogs.com/">管理</a></li>
 46 </ul>
 47         <div class="blogStats">
 48             
 49             <div id="blog_stats">
 50 <span id="stats_post_count">随笔 - 8&nbsp; </span>
 51 <span id="stats_article_count">文章 - 0&nbsp; </span>
 52 <span id="stats-comment_count">评论 - 1</span>
 53 </div>
 54             
 55         </div><!--end: blogStats -->
 56     </div><!--end: navigator 博客导航栏 -->
 57 </div><!--end: header 头部 -->
 58 
 59 <div id="main">
 60     <div id="mainContent">
 61     <div class="forFlow">
 62         
 63 <div id="post_detail">
 64 <!--done-->
 65 <div id="topics">
 66     <div class = "post">
 67         <h1 class = "postTitle">
 68             <a id="cb_post_title_url" class="postTitle2" href="https://www.cnblogs.com/zhangkanghui/p/9577714.html">D09——C语言基础学PYTHON</a>
 69         </h1>
 70         <div class="clear"></div>
 71         <div class="postBody">
 72             <div id="cnblogs_post_body" class="blogpost-body"><p><span style="font-size: 18pt; background-color: #ffff00"><strong>C语言基础学习PYTHON——基础学习D09</strong></span></p>
 73 <blockquote>
 74 <p><strong><span style="font-size: 18px">20180903内容纲要:</span></strong></p>
 75 </blockquote>
 76 <p>&nbsp;</p>
 77 <p><strong><strong>   线程、进程</strong></strong></p>
 78 <p>&nbsp;</p>
 79 <p><strong><strong>  1、paramiko</strong></strong></p>
 80 <p><strong><strong>  2、线程、进程初识</strong></strong></p>
 81 <p><strong><strong>  3、线程</strong></strong></p>
 82 <p><strong><strong>     (1)线程的调用方式</strong></strong></p>
 83 <p><strong><strong>     (2)join</strong></strong></p>
 84 <p><strong><strong>     (3)线程锁、递归锁、信号量</strong></strong></p>
 85 <p><strong>     (4)Timer</strong></p>
 86 <p><strong>     (5)Event</strong></p>
 87 <p><strong>     (6)Queue队列</strong></p>
 88 <p><strong>  4、小结</strong></p>
 89 <p><strong>  5、练习:简单主机批量管理工具</strong></p>
 90 <p><strong>&nbsp;</strong></p>
 91 <blockquote>
 92 <p><span style="font-size: 14pt"><strong>1、paramiko</strong></span></p>
 93 </blockquote>
 94 <p>paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能。这是一个第三方的软件包,使用之前需要安装。</p>
 95 <p>我个人觉得,这个在Windows上不太好用。在windows上python3需要安装vs2010,但我装了之后还是不行,可能是我自己的原因,在python2.7上好像可以,没试过。</p>
 96 <p>这有链接:<a href="https://blog.csdn.net/songfreeman/article/details/50920767" target="_blank">https://blog.csdn.net/songfreeman/article/details/50920767<br></a></p>
 97 <p>很详细!</p>
 98 <p>&nbsp;</p>
 99 <blockquote>
100 <p><span style="font-size: 14pt"><strong>2 线程、进程初识</strong></span></p>
101 
102 
103 
104 
105 
106 
107 </blockquote>
108 <h3>什么是线程(thread)?</h3>
109 <p>线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。</p>
110 <p>一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务</p>
111 <p>A thread is an execution context, which is all the information a CPU needs to execute a stream of instructions.</p>
112 <div class="cnblogs_code"><img id="code_img_closed_f52f3cbd-a865-4c8a-bd82-2732e6fb8022" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_f52f3cbd-a865-4c8a-bd82-2732e6fb8022" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
113 <div id="cnblogs_code_open_f52f3cbd-a865-4c8a-bd82-2732e6fb8022" class="cnblogs_code_hide">
114 <pre>Suppose you<span style="color: #800000">'</span><span style="color: #800000">re reading a book, and you want to take a break right now, but you want to be able to come back and resume reading from the exact point where you stopped. One way to achieve that is by jotting down the page number, line number, and word number. So your execution context for reading a book is these 3 numbers.</span>
115 <span style="color: #000000">
116 If you have a roommate, </span><span style="color: #0000ff">and</span> she<span style="color: #800000">'</span><span style="color: #800000">s using the same technique, she can take the book while you</span><span style="color: #800000">'</span>re <span style="color: #0000ff">not</span> using it, <span style="color: #0000ff">and</span> resume reading <span style="color: #0000ff">from</span> where she stopped. Then you can take it back, <span style="color: #0000ff">and</span> resume it <span style="color: #0000ff">from</span><span style="color: #000000"> where you were.
117 
118 Threads work </span><span style="color: #0000ff">in</span> the same way. A CPU <span style="color: #0000ff">is</span> giving you the illusion that it<span style="color: #800000">'</span><span style="color: #800000">s doing multiple computations at the same time. It does that by spending a bit of time on each computation. It can do that because it has an execution context for each computation. Just like you can share a book with your friend, many tasks can share a CPU.</span>
119 <span style="color: #000000">
120 On a more technical level, an execution context (therefore a thread) consists of the values of the CPU</span><span style="color: #800000">'</span><span style="color: #800000">s registers.</span>
121 <span style="color: #000000">
122 Last: threads are different </span><span style="color: #0000ff">from</span> processes. A thread <span style="color: #0000ff">is</span> a context of execution, <span style="color: #0000ff">while</span> a process <span style="color: #0000ff">is</span> a bunch of resources associated with a computation. A process can have one <span style="color: #0000ff">or</span><span style="color: #000000"> many threads.
123 
124 Clarification: the resources associated with a process include memory pages (all the threads </span><span style="color: #0000ff">in</span> a process have the same view of the memory), file descriptors (e.g., open sockets), <span style="color: #0000ff">and</span> security credentials (e.g., the ID of the user who started the process).</pre>
125 </div>
126 <span class="cnblogs_code_collapse">英文解释</span></div>
127 <h3>什么是进程(process)?</h3>
128 <p>程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程。</p>
129 <p>程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。</p>
130 <p>An executing instance of a program is called a process.</p>
131 <div class="cnblogs_code"><img id="code_img_closed_a81bb69d-34be-4e5b-86b5-d9787eee621a" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a81bb69d-34be-4e5b-86b5-d9787eee621a" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
132 <div id="cnblogs_code_open_a81bb69d-34be-4e5b-86b5-d9787eee621a" class="cnblogs_code_hide">
133 <pre>Each process provides the resources needed to execute a program. A process has a virtual address space, executable code, open handles to system objects, a security context, a unique process identifier, environment variables, a priority <span style="color: #0000ff">class</span>, minimum <span style="color: #0000ff">and</span> maximum working set sizes, <span style="color: #0000ff">and</span> at least one thread of execution. Each process <span style="color: #0000ff">is</span> started with a single thread, often called the primary thread, but can create additional threads <span style="color: #0000ff">from</span> any of its threads.</pre>
134 </div>
135 <span class="cnblogs_code_collapse">英文解释</span></div>
136 <p>&nbsp;</p>
137 <p>那么他们的区别呢?</p>
138 <h3>进程与线程的区别?</h3>
139 <p>线程:是操作系统最小的调度单位。 是一串指令的集合。</p>
140 <p>进程:要操作cpu必须先创建一个线程</p>
141 <p>所有在同一个进程里的线程是共享一块内存空间</p>
142 <p>&nbsp;</p>
143 <div class="cnblogs_code"><img id="code_img_closed_70388922-c789-45c9-a798-77fd21c98ac2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_70388922-c789-45c9-a798-77fd21c98ac2" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
144 <div id="cnblogs_code_open_70388922-c789-45c9-a798-77fd21c98ac2" class="cnblogs_code_hide">
145 <pre><span style="color: #008080"> 1</span> 1<span style="color: #000000">、Threads share the address space of the process that created it; processes have their own address space.
146 </span><span style="color: #008080"> 2</span> 1<span style="color: #000000">、线程共享内存空间,进程的内存是独立的
147 </span><span style="color: #008080"> 3</span> 
148 <span style="color: #008080"> 4</span> 2<span style="color: #000000">、Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
149 </span><span style="color: #008080"> 5</span> 
150 <span style="color: #008080"> 6</span> 3<span style="color: #000000">、Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
151 </span><span style="color: #008080"> 7</span> 3<span style="color: #000000">、两个进程之间可以直接交流,两个进程进行通讯,必须通过一个中间代理来实现。
152 </span><span style="color: #008080"> 8</span> 
153 <span style="color: #008080"> 9</span> 4<span style="color: #000000">、New threads are easily created; new processes require duplication of the parent process.
154 </span><span style="color: #008080">10</span> 4<span style="color: #000000">、创建新线程很简单。创建新进程需要对其父进程进行一次克隆
155 </span><span style="color: #008080">11</span> 
156 <span style="color: #008080">12</span> 5<span style="color: #000000">、Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
157 </span><span style="color: #008080">13</span> 5<span style="color: #000000">、一个线程可以控制和操作同意进程里的其他线程,但是进程只能操作子进程
158 </span><span style="color: #008080">14</span> 
159 <span style="color: #008080">15</span> 6、Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does <span style="color: #0000ff">not</span><span style="color: #000000"> affect child processes.
160 </span><span style="color: #008080">16</span>  </pre>
161 </div>
162 <span class="cnblogs_code_collapse">进程与线程的区别</span></div>
163 <p>&nbsp;</p>
164 <blockquote>
165 <p><span style="font-size: 14pt"><strong>3 线程</strong></span></p>
166 </blockquote>
167 <p><span style="font-size: 14px"><strong>(1)线程的调用方式</strong></span></p>
168 <p><span style="font-size: 14px">直接调用:</span></p>
169 <div class="cnblogs_code"><img id="code_img_closed_8cc59f33-5a03-49bd-b99c-591a20547e10" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8cc59f33-5a03-49bd-b99c-591a20547e10" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
170 <div id="cnblogs_code_open_8cc59f33-5a03-49bd-b99c-591a20547e10" class="cnblogs_code_hide">
171 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
172 <span style="color: #008080"> 2</span> 
173 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
174 </span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
175 </span><span style="color: #008080"> 5</span> 
176 <span style="color: #008080"> 6</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run(n):
177 </span><span style="color: #008080"> 7</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">task</span><span style="color: #800000">"</span><span style="color: #000000">,n,threading.current_thread())
178 </span><span style="color: #008080"> 8</span>     time.sleep(2<span style="color: #000000">)
179 </span><span style="color: #008080"> 9</span> <span style="color: #800000">'''</span><span style="color: #800000">#这里是只有两个线程,那么更多线程呢?
180 </span><span style="color: #008080">10</span> <span style="color: #800000">t1 = threading.Thread(target=run,args=("t1",))
181 </span><span style="color: #008080">11</span> <span style="color: #800000">t2 = threading.Thread(target=run,args=("t2",))
182 </span><span style="color: #008080">12</span> <span style="color: #800000">t1.start()
183 </span><span style="color: #008080">13</span> <span style="color: #800000">t2.start()
184 </span><span style="color: #008080">14</span> <span style="color: #800000">'''</span>
185 <span style="color: #008080">15</span> <span style="color: #008000">#</span><span style="color: #008000">这是一个多线程,那么我们来看一下他整个程序的执行时间为什么不是2s</span>
186 <span style="color: #008080">16</span> start_time =<span style="color: #000000"> time.time()
187 </span><span style="color: #008080">17</span> <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(50<span style="color: #000000">):
188 </span><span style="color: #008080">18</span>     t = threading.Thread(target=run,args=(<span style="color: #800000">"</span><span style="color: #800000">t-%s</span><span style="color: #800000">"</span> %i,))   <span style="color: #008000">#</span><span style="color: #008000">这个地方args必须有,。。因为这是默认一个元组</span>
189 <span style="color: #008080">19</span> <span style="color: #000000">    t.start()
190 </span><span style="color: #008080">20</span>     <span style="color: #008000">#</span><span style="color: #008000">t.join()       #这样可以把并行变成串行</span>
191 <span style="color: #008080">21</span> 
192 <span style="color: #008080">22</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">mian threading has finished....</span><span style="color: #800000">"</span><span style="color: #000000">,threading.current_thread(),threading.active_count())
193 </span><span style="color: #008080">23</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">cost:</span><span style="color: #800000">"</span>,time.time()-<span style="color: #000000">start_time)
194 </span><span style="color: #008080">24</span> <span style="color: #008000">#</span><span style="color: #008000">这是因为主线程和子线程没关系。主线程不会等子线程执行完毕才计算时间</span>
195 <span style="color: #008080">25</span> <span style="color: #008000">#</span><span style="color: #008000">那接下来如果想要等所有的线程结束然后打印程序执行时间可以这么干</span>
196 <span style="color: #008080">26</span> <span style="color: #800000">'''</span>
197 <span style="color: #008080">27</span> 
198 <span style="color: #008080">28</span> <span style="color: #800000">import threading
199 </span><span style="color: #008080">29</span> <span style="color: #800000">import time
200 </span><span style="color: #008080">30</span> 
201 <span style="color: #008080">31</span> <span style="color: #800000">def run(n):
202 </span><span style="color: #008080">32</span> <span style="color: #800000">    print("task",n)
203 </span><span style="color: #008080">33</span> <span style="color: #800000">    time.sleep(2)
204 </span><span style="color: #008080">34</span>     
205 <span style="color: #008080">35</span> 
206 <span style="color: #008080">36</span> <span style="color: #800000">start_time = time.time()
207 </span><span style="color: #008080">37</span> <span style="color: #800000">t_obj =[]       #存线程实例
208 </span><span style="color: #008080">38</span> <span style="color: #800000">for i in range(50):
209 </span><span style="color: #008080">39</span> <span style="color: #800000">    t = threading.Thread(target=run,args=("t-%s" %i,))   #这个地方args必须有,。。因为这是默认一个元组
210 </span><span style="color: #008080">40</span> <span style="color: #800000">    #t.setDaemon(True)              #把当前线程设置成守护线程,必须在启动strat之前
211 </span><span style="color: #008080">41</span> <span style="color: #800000">    t.start()
212 </span><span style="color: #008080">42</span> <span style="color: #800000">    t_obj.append(t) #为了不阻塞后面线程的启动,不在这里加join,先放到一个列表里
213 </span><span style="color: #008080">43</span> <span style="color: #800000">for i in t_obj:        #循环线程实例列表,等待所有线程执行完毕
214 </span><span style="color: #008080">44</span> <span style="color: #800000">    t.join()
215 </span><span style="color: #008080">45</span>     
216 <span style="color: #008080">46</span> <span style="color: #800000">print("cost:",time.time()-start_time)
217 </span><span style="color: #008080">47</span> 
218 <span style="color: #008080">48</span> <span style="color: #800000">'''</span></pre>
219 </div>
220 <span class="cnblogs_code_collapse">直接调用</span></div>
221 <p>继承式调用</p>
222 <div class="cnblogs_code"><img id="code_img_closed_9cc95b50-0dd2-4780-98f6-e19ce4f49bd9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9cc95b50-0dd2-4780-98f6-e19ce4f49bd9" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
223 <div id="cnblogs_code_open_9cc95b50-0dd2-4780-98f6-e19ce4f49bd9" class="cnblogs_code_hide">
224 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
225 <span style="color: #008080"> 2</span> 
226 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
227 </span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
228 </span><span style="color: #008080"> 5</span> 
229 <span style="color: #008080"> 6</span> <span style="color: #0000ff">class</span><span style="color: #000000"> MyThread(threading.Thread):
230 </span><span style="color: #008080"> 7</span>     <span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,n,sleep_time):
231 </span><span style="color: #008080"> 8</span>         super(MyThread,self).<span style="color: #800080">__init__</span><span style="color: #000000">()
232 </span><span style="color: #008080"> 9</span>         self.n =<span style="color: #000000"> n
233 </span><span style="color: #008080">10</span>         self.sleep_time =<span style="color: #000000"> sleep_time
234 </span><span style="color: #008080">11</span> 
235 <span style="color: #008080">12</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> run(self):
236 </span><span style="color: #008080">13</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">running task</span><span style="color: #800000">"</span><span style="color: #000000">,self.n)
237 </span><span style="color: #008080">14</span> <span style="color: #000000">        time.sleep(self.sleep_time)
238 </span><span style="color: #008080">15</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">task done</span><span style="color: #800000">"</span><span style="color: #000000">,self.n)
239 </span><span style="color: #008080">16</span> 
240 <span style="color: #008080">17</span> t1 =MyThread(<span style="color: #800000">"</span><span style="color: #800000">t1</span><span style="color: #800000">"</span>,2<span style="color: #000000">)
241 </span><span style="color: #008080">18</span> t2 =MyThread(<span style="color: #800000">"</span><span style="color: #800000">t2</span><span style="color: #800000">"</span>,4<span style="color: #000000">)
242 </span><span style="color: #008080">19</span> 
243 <span style="color: #008080">20</span> <span style="color: #000000">t1.start()
244 </span><span style="color: #008080">21</span> <span style="color: #000000">t2.start()
245 </span><span style="color: #008080">22</span> 
246 <span style="color: #008080">23</span> <span style="color: #008000">#</span><span style="color: #008000">t1.join()</span>
247 <span style="color: #008080">24</span> <span style="color: #008000">#</span><span style="color: #008000">t2.join()</span>
248 <span style="color: #008080">25</span> 
249 <span style="color: #008080">26</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">mian threading....</span><span style="color: #800000">"</span>)</pre>
250 </div>
251 <span class="cnblogs_code_collapse">继承式调用</span></div>
252 <p><strong>(2)join&amp;Daemon</strong></p>
253 <p>其实join就是wait。Daemon就是守护线程。</p>
254 <p>Some threads do background tasks, like sending keepalive packets, or performing periodic garbage collection, or whatever. These are only useful when the main program is running, and it's okay to kill them off once the other, non-daemon, threads have exited.</p>
255 <p>Without daemon threads, you'd have to keep track of them, and tell them to exit, before your program can completely quit. By setting them as daemon threads, you can let them run and forget about them, and when your program quits, any daemon threads are killed automatically.</p>
256 <div class="cnblogs_code"><img id="code_img_closed_2deaebbd-3a16-45bf-ae48-b77a3abc102d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_2deaebbd-3a16-45bf-ae48-b77a3abc102d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
257 <div id="cnblogs_code_open_2deaebbd-3a16-45bf-ae48-b77a3abc102d" class="cnblogs_code_hide">
258 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
259 <span style="color: #008080"> 2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
260 </span><span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
261 </span><span style="color: #008080"> 4</span> 
262 <span style="color: #008080"> 5</span> 
263 <span style="color: #008080"> 6</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run(n):
264 </span><span style="color: #008080"> 7</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">[%s]------running----\n</span><span style="color: #800000">'</span> %<span style="color: #000000"> n)
265 </span><span style="color: #008080"> 8</span>     time.sleep(2<span style="color: #000000">)
266 </span><span style="color: #008080"> 9</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">--done--</span><span style="color: #800000">'</span><span style="color: #000000">)
267 </span><span style="color: #008080">10</span> 
268 <span style="color: #008080">11</span> 
269 <span style="color: #008080">12</span> <span style="color: #0000ff">def</span><span style="color: #000000"> main():
270 </span><span style="color: #008080">13</span>     <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(5<span style="color: #000000">):
271 </span><span style="color: #008080">14</span>         t = threading.Thread(target=run, args=<span style="color: #000000">[i, ])
272 </span><span style="color: #008080">15</span> <span style="color: #000000">        t.start()
273 </span><span style="color: #008080">16</span>         t.join(1<span style="color: #000000">)
274 </span><span style="color: #008080">17</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">starting thread</span><span style="color: #800000">'</span><span style="color: #000000">, t.getName())
275 </span><span style="color: #008080">18</span> 
276 <span style="color: #008080">19</span> 
277 <span style="color: #008080">20</span> m = threading.Thread(target=main, args=<span style="color: #000000">[])
278 </span><span style="color: #008080">21</span> m.setDaemon(True)  <span style="color: #008000">#</span><span style="color: #008000"> 将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务</span>
279 <span style="color: #008080">22</span> <span style="color: #000000">m.start()
280 </span><span style="color: #008080">23</span> <span style="color: #000000">m.join()
281 </span><span style="color: #008080">24</span> <span style="color: #008000">#</span><span style="color: #008000"> m.join(timeout=2)</span>
282 <span style="color: #008080">25</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">---main thread done----</span><span style="color: #800000">"</span>)</pre>
283 </div>
284 <span class="cnblogs_code_collapse">join&amp;Daemon</span></div>
285 <div class="cnblogs_code"><img id="code_img_closed_d1c17aec-1b1a-487c-ab9c-638d96b8f0a9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d1c17aec-1b1a-487c-ab9c-638d96b8f0a9" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
286 <div id="cnblogs_code_open_d1c17aec-1b1a-487c-ab9c-638d96b8f0a9" class="cnblogs_code_hide">
287 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
288 <span style="color: #008080"> 2</span> 
289 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
290 </span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
291 </span><span style="color: #008080"> 5</span> 
292 <span style="color: #008080"> 6</span> <span style="color: #0000ff">class</span><span style="color: #000000"> MyThread(threading.Thread):
293 </span><span style="color: #008080"> 7</span>     <span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,n,sleep_time):
294 </span><span style="color: #008080"> 8</span>         super(MyThread,self).<span style="color: #800080">__init__</span><span style="color: #000000">()
295 </span><span style="color: #008080"> 9</span>         self.n =<span style="color: #000000"> n
296 </span><span style="color: #008080">10</span>         self.sleep_time =<span style="color: #000000"> sleep_time
297 </span><span style="color: #008080">11</span> 
298 <span style="color: #008080">12</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> run(self):
299 </span><span style="color: #008080">13</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">running task</span><span style="color: #800000">"</span><span style="color: #000000">,self.n)
300 </span><span style="color: #008080">14</span> <span style="color: #000000">        time.sleep(self.sleep_time)
301 </span><span style="color: #008080">15</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">task done</span><span style="color: #800000">"</span><span style="color: #000000">,self.n)
302 </span><span style="color: #008080">16</span> 
303 <span style="color: #008080">17</span> t1 =MyThread(<span style="color: #800000">"</span><span style="color: #800000">t1</span><span style="color: #800000">"</span>,2<span style="color: #000000">)
304 </span><span style="color: #008080">18</span> t2 =MyThread(<span style="color: #800000">"</span><span style="color: #800000">t2</span><span style="color: #800000">"</span>,4<span style="color: #000000">)
305 </span><span style="color: #008080">19</span> 
306 <span style="color: #008080">20</span> <span style="color: #000000">t1.start()
307 </span><span style="color: #008080">21</span> <span style="color: #000000">t2.start()
308 </span><span style="color: #008080">22</span> 
309 <span style="color: #008080">23</span> <span style="color: #000000">t1.join()
310 </span><span style="color: #008080">24</span> <span style="color: #000000">t2.join()
311 </span><span style="color: #008080">25</span> 
312 <span style="color: #008080">26</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">mian threading....</span><span style="color: #800000">"</span>)</pre>
313 </div>
314 <span class="cnblogs_code_collapse">join1</span></div>
315 <div class="cnblogs_code"><img id="code_img_closed_14a3cdfa-7082-4d31-a48d-3fdae50438a9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_14a3cdfa-7082-4d31-a48d-3fdae50438a9" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
316 <div id="cnblogs_code_open_14a3cdfa-7082-4d31-a48d-3fdae50438a9" class="cnblogs_code_hide">
317 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
318 </span><span style="color: #008080"> 2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
319 </span><span style="color: #008080"> 3</span> 
320 <span style="color: #008080"> 4</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run(n):
321 </span><span style="color: #008080"> 5</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">task</span><span style="color: #800000">"</span><span style="color: #000000">,n)
322 </span><span style="color: #008080"> 6</span>     time.sleep(2<span style="color: #000000">)
323 </span><span style="color: #008080"> 7</span>     
324 <span style="color: #008080"> 8</span> start_time =<span style="color: #000000"> time.time()
325 </span><span style="color: #008080"> 9</span> t_obj =[]       <span style="color: #008000">#</span><span style="color: #008000">存线程实例</span>
326 <span style="color: #008080">10</span> <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(50<span style="color: #000000">):
327 </span><span style="color: #008080">11</span>     t = threading.Thread(target=run,args=(<span style="color: #800000">"</span><span style="color: #800000">t-%s</span><span style="color: #800000">"</span> %i,))   <span style="color: #008000">#</span><span style="color: #008000">这个地方args必须有,。。因为这是默认一个元组</span>
328 <span style="color: #008080">12</span>     <span style="color: #008000">#</span><span style="color: #008000">t.setDaemon(True)              #把当前线程设置成守护线程,必须在启动strat之前</span>
329 <span style="color: #008080">13</span> <span style="color: #000000">    t.start()
330 </span><span style="color: #008080">14</span>     t_obj.append(t) <span style="color: #008000">#</span><span style="color: #008000">为了不阻塞后面线程的启动,不在这里加join,先放到一个列表里</span>
331 <span style="color: #008080">15</span> <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> t_obj:        <span style="color: #008000">#</span><span style="color: #008000">循环线程实例列表,等待所有线程执行完毕</span>
332 <span style="color: #008080">16</span> <span style="color: #000000">    t.join()
333 </span><span style="color: #008080">17</span>     
334 <span style="color: #008080">18</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">cost:</span><span style="color: #800000">"</span>,time.time()-start_time)</pre>
335 </div>
336 <span class="cnblogs_code_collapse">join2</span></div>
337 <p><strong>(3)线程锁/递归锁/信号量</strong></p>
338 <p><strong>线程锁</strong></p>
339 <p>一个进程下可以启动多个线程,多个线程共享父进程的内存空间,也就意味着每个线程可以访问同一份数据,此时,如果2个线程同时要修改同一份数据,会出现什么状况?</p>
340 <div class="cnblogs_code"><img id="code_img_closed_37379dfa-a22b-422a-b0d0-ea12dc9490c0" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_37379dfa-a22b-422a-b0d0-ea12dc9490c0" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
341 <div id="cnblogs_code_open_37379dfa-a22b-422a-b0d0-ea12dc9490c0" class="cnblogs_code_hide">
342 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
343 </span><span style="color: #008080"> 2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
344 </span><span style="color: #008080"> 3</span>  
345 <span style="color: #008080"> 4</span> <span style="color: #0000ff">def</span><span style="color: #000000"> addNum():
346 </span><span style="color: #008080"> 5</span>     <span style="color: #0000ff">global</span> num <span style="color: #008000">#</span><span style="color: #008000">在每个线程中都获取这个全局变量</span>
347 <span style="color: #008080"> 6</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">--get num:</span><span style="color: #800000">'</span><span style="color: #000000">,num )
348 </span><span style="color: #008080"> 7</span>     time.sleep(1<span style="color: #000000">)
349 </span><span style="color: #008080"> 8</span>     lock.acquire() <span style="color: #008000">#</span><span style="color: #008000">修改数据前加锁</span>
350 <span style="color: #008080"> 9</span>     num  -=1 <span style="color: #008000">#</span><span style="color: #008000">对此公共变量进行-1操作</span>
351 <span style="color: #008080">10</span>     lock.release() <span style="color: #008000">#</span><span style="color: #008000">修改后释放</span>
352 <span style="color: #008080">11</span>  
353 <span style="color: #008080">12</span> num = 100  <span style="color: #008000">#</span><span style="color: #008000">设定一个共享变量</span>
354 <span style="color: #008080">13</span> thread_list =<span style="color: #000000"> []
355 </span><span style="color: #008080">14</span> lock = threading.Lock() <span style="color: #008000">#</span><span style="color: #008000">生成全局锁</span>
356 <span style="color: #008080">15</span> <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(100<span style="color: #000000">):
357 </span><span style="color: #008080">16</span>     t = threading.Thread(target=<span style="color: #000000">addNum)
358 </span><span style="color: #008080">17</span> <span style="color: #000000">    t.start()
359 </span><span style="color: #008080">18</span> <span style="color: #000000">    thread_list.append(t)
360 </span><span style="color: #008080">19</span>  
361 <span style="color: #008080">20</span> <span style="color: #0000ff">for</span> t <span style="color: #0000ff">in</span> thread_list: <span style="color: #008000">#</span><span style="color: #008000">等待所有线程执行完毕</span>
362 <span style="color: #008080">21</span> <span style="color: #000000">    t.join()
363 </span><span style="color: #008080">22</span>  
364 <span style="color: #008080">23</span> <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">final num:</span><span style="color: #800000">'</span>, num )</pre>
365 </div>
366 <span class="cnblogs_code_collapse">线程锁</span></div>
367 <p><strong>递归锁</strong></p>
368 <p>就是在一个大锁中还要再包含子锁</p>
369 <div class="cnblogs_code"><img id="code_img_closed_8dbacbd9-7372-40b1-9ea6-8418bdd0e6da" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8dbacbd9-7372-40b1-9ea6-8418bdd0e6da" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
370 <div id="cnblogs_code_open_8dbacbd9-7372-40b1-9ea6-8418bdd0e6da" class="cnblogs_code_hide">
371 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading,time
372 </span><span style="color: #008080"> 2</span>  
373 <span style="color: #008080"> 3</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run1():
374 </span><span style="color: #008080"> 4</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">grab the first part data</span><span style="color: #800000">"</span><span style="color: #000000">)
375 </span><span style="color: #008080"> 5</span> <span style="color: #000000">    lock.acquire()
376 </span><span style="color: #008080"> 6</span>     <span style="color: #0000ff">global</span><span style="color: #000000"> num
377 </span><span style="color: #008080"> 7</span>     num +=1
378 <span style="color: #008080"> 8</span> <span style="color: #000000">    lock.release()
379 </span><span style="color: #008080"> 9</span>     <span style="color: #0000ff">return</span><span style="color: #000000"> num
380 </span><span style="color: #008080">10</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run2():
381 </span><span style="color: #008080">11</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">grab the second part data</span><span style="color: #800000">"</span><span style="color: #000000">)
382 </span><span style="color: #008080">12</span> <span style="color: #000000">    lock.acquire()
383 </span><span style="color: #008080">13</span>     <span style="color: #0000ff">global</span><span style="color: #000000">  num2
384 </span><span style="color: #008080">14</span>     num2+=1
385 <span style="color: #008080">15</span> <span style="color: #000000">    lock.release()
386 </span><span style="color: #008080">16</span>     <span style="color: #0000ff">return</span><span style="color: #000000"> num2
387 </span><span style="color: #008080">17</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run3():
388 </span><span style="color: #008080">18</span> <span style="color: #000000">    lock.acquire()
389 </span><span style="color: #008080">19</span>     res =<span style="color: #000000"> run1()
390 </span><span style="color: #008080">20</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">--------between run1 and run2-----</span><span style="color: #800000">'</span><span style="color: #000000">)
391 </span><span style="color: #008080">21</span>     res2 =<span style="color: #000000"> run2()
392 </span><span style="color: #008080">22</span> <span style="color: #000000">    lock.release()
393 </span><span style="color: #008080">23</span>     <span style="color: #0000ff">print</span><span style="color: #000000">(res,res2)
394 </span><span style="color: #008080">24</span>  
395 <span style="color: #008080">25</span>  
396 <span style="color: #008080">26</span> <span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">'</span><span style="color: #800000">__main__</span><span style="color: #800000">'</span><span style="color: #000000">:
397 </span><span style="color: #008080">27</span>  
398 <span style="color: #008080">28</span>     num,num2 =<span style="color: #000000"> 0,0
399 </span><span style="color: #008080">29</span>     lock =<span style="color: #000000"> threading.RLock()
400 </span><span style="color: #008080">30</span>     <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(10<span style="color: #000000">):
401 </span><span style="color: #008080">31</span>         t = threading.Thread(target=<span style="color: #000000">run3)
402 </span><span style="color: #008080">32</span> <span style="color: #000000">        t.start()
403 </span><span style="color: #008080">33</span>  
404 <span style="color: #008080">34</span> <span style="color: #0000ff">while</span> threading.active_count() != 1<span style="color: #000000">:
405 </span><span style="color: #008080">35</span>     <span style="color: #0000ff">print</span><span style="color: #000000">(threading.active_count())
406 </span><span style="color: #008080">36</span> <span style="color: #0000ff">else</span><span style="color: #000000">:
407 </span><span style="color: #008080">37</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">----all threads done---</span><span style="color: #800000">'</span><span style="color: #000000">)
408 </span><span style="color: #008080">38</span>     <span style="color: #0000ff">print</span>(num,num2)</pre>
409 </div>
410 <span class="cnblogs_code_collapse">递归锁</span></div>
411 <p><strong>信号量(Semaphore)</strong></p>
412 <p>互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 。</p>
413 <p>比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。</p>
414 <div class="cnblogs_code"><img id="code_img_closed_77906072-186c-4497-8adf-816d6a972222" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_77906072-186c-4497-8adf-816d6a972222" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
415 <div id="cnblogs_code_open_77906072-186c-4497-8adf-816d6a972222" class="cnblogs_code_hide">
416 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading,time
417 </span><span style="color: #008080"> 2</span>  
418 <span style="color: #008080"> 3</span> <span style="color: #0000ff">def</span><span style="color: #000000"> run(n):
419 </span><span style="color: #008080"> 4</span> <span style="color: #000000">    semaphore.acquire()
420 </span><span style="color: #008080"> 5</span>     time.sleep(1<span style="color: #000000">)
421 </span><span style="color: #008080"> 6</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">run the thread: %s\n</span><span style="color: #800000">"</span> %<span style="color: #000000">n)
422 </span><span style="color: #008080"> 7</span> <span style="color: #000000">    semaphore.release()
423 </span><span style="color: #008080"> 8</span>  
424 <span style="color: #008080"> 9</span> <span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">'</span><span style="color: #800000">__main__</span><span style="color: #800000">'</span><span style="color: #000000">:
425 </span><span style="color: #008080">10</span>  
426 <span style="color: #008080">11</span>     num=<span style="color: #000000"> 0
427 </span><span style="color: #008080">12</span>     semaphore  = threading.BoundedSemaphore(5) <span style="color: #008000">#</span><span style="color: #008000">最多允许5个线程同时运行</span>
428 <span style="color: #008080">13</span>     <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(20<span style="color: #000000">):
429 </span><span style="color: #008080">14</span>         t = threading.Thread(target=run,args=<span style="color: #000000">(i,))
430 </span><span style="color: #008080">15</span> <span style="color: #000000">        t.start()
431 </span><span style="color: #008080">16</span>  
432 <span style="color: #008080">17</span> <span style="color: #0000ff">while</span> threading.active_count() != 1<span style="color: #000000">:
433 </span><span style="color: #008080">18</span>     <span style="color: #0000ff">pass</span> <span style="color: #008000">#</span><span style="color: #008000">print threading.active_count()</span>
434 <span style="color: #008080">19</span> <span style="color: #0000ff">else</span><span style="color: #000000">:
435 </span><span style="color: #008080">20</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">----all threads done---</span><span style="color: #800000">'</span><span style="color: #000000">)
436 </span><span style="color: #008080">21</span>     <span style="color: #0000ff">print</span>(num)</pre>
437 </div>
438 <span class="cnblogs_code_collapse">信号量</span></div>
439 <p><strong>(4)Timer</strong></p>
440 <p>This class represents an action that should be run only after a certain amount of time has passed。</p>
441 <div class="cnblogs_code"><img id="code_img_closed_5decea23-4aca-4e15-82a1-14d039aeb20e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_5decea23-4aca-4e15-82a1-14d039aeb20e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
442 <div id="cnblogs_code_open_5decea23-4aca-4e15-82a1-14d039aeb20e" class="cnblogs_code_hide">
443 <pre><span style="color: #008080">1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
444 <span style="color: #008080">2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
445 </span><span style="color: #008080">3</span> <span style="color: #0000ff">def</span><span style="color: #000000"> hello():
446 </span><span style="color: #008080">4</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">hello, world</span><span style="color: #800000">"</span><span style="color: #000000">)
447 </span><span style="color: #008080">5</span> 
448 <span style="color: #008080">6</span> t = threading.Thread(target=<span style="color: #000000">hello)
449 </span><span style="color: #008080">7</span> t = threading.Timer(30.0<span style="color: #000000">, hello)
450 </span><span style="color: #008080">8</span> t.start()  <span style="color: #008000">#</span><span style="color: #008000"> after 30 seconds, "hello, world" will be printed</span></pre>
451 </div>
452 <span class="cnblogs_code_collapse">Timer</span></div>
453 <p><strong>(5)Event</strong></p>
454 <p>An event is a simple synchronization object;通过Event来实现两个或多个线程间的交互。</p>
455 <p>the event represents an internal flag, and threads&nbsp;can wait for the flag to be set, or set or clear the flag themselves.</p>
456 <p>event.wait()</p>
457 <p>event.set()</p>
458 <p>event.clear()</p>
459 <p>下面是一个红绿灯的例子,即起动一个线程做交通指挥灯,生成几个线程做车辆,车辆行驶按红灯停,绿灯行的规则。</p>
460 <div class="cnblogs_code"><img id="code_img_closed_bc894591-a7dd-4526-b4d1-1e92981f2a96" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_bc894591-a7dd-4526-b4d1-1e92981f2a96" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
461 <div id="cnblogs_code_open_bc894591-a7dd-4526-b4d1-1e92981f2a96" class="cnblogs_code_hide">
462 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading,time
463 </span><span style="color: #008080"> 2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> random
464 </span><span style="color: #008080"> 3</span> <span style="color: #0000ff">def</span><span style="color: #000000"> light():
465 </span><span style="color: #008080"> 4</span>     <span style="color: #0000ff">if</span> <span style="color: #0000ff">not</span><span style="color: #000000"> event.isSet():
466 </span><span style="color: #008080"> 5</span>         event.set() <span style="color: #008000">#</span><span style="color: #008000">wait就不阻塞 #绿灯状态</span>
467 <span style="color: #008080"> 6</span>     count =<span style="color: #000000"> 0
468 </span><span style="color: #008080"> 7</span>     <span style="color: #0000ff">while</span><span style="color: #000000"> True:
469 </span><span style="color: #008080"> 8</span>         <span style="color: #0000ff">if</span> count &lt; 10<span style="color: #000000">:
470 </span><span style="color: #008080"> 9</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">\033[42;1m--green light on---\033[0m</span><span style="color: #800000">'</span><span style="color: #000000">)
471 </span><span style="color: #008080">10</span>         <span style="color: #0000ff">elif</span> count &lt;13<span style="color: #000000">:
472 </span><span style="color: #008080">11</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">\033[43;1m--yellow light on---\033[0m</span><span style="color: #800000">'</span><span style="color: #000000">)
473 </span><span style="color: #008080">12</span>         <span style="color: #0000ff">elif</span> count &lt;20<span style="color: #000000">:
474 </span><span style="color: #008080">13</span>             <span style="color: #0000ff">if</span><span style="color: #000000"> event.isSet():
475 </span><span style="color: #008080">14</span> <span style="color: #000000">                event.clear()
476 </span><span style="color: #008080">15</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">'</span><span style="color: #800000">\033[41;1m--red light on---\033[0m</span><span style="color: #800000">'</span><span style="color: #000000">)
477 </span><span style="color: #008080">16</span>         <span style="color: #0000ff">else</span><span style="color: #000000">:
478 </span><span style="color: #008080">17</span>             count =<span style="color: #000000"> 0
479 </span><span style="color: #008080">18</span>             event.set() <span style="color: #008000">#</span><span style="color: #008000">打开绿灯</span>
480 <span style="color: #008080">19</span>         time.sleep(1<span style="color: #000000">)
481 </span><span style="color: #008080">20</span>         count +=1
482 <span style="color: #008080">21</span> <span style="color: #0000ff">def</span><span style="color: #000000"> car(n):
483 </span><span style="color: #008080">22</span>     <span style="color: #0000ff">while</span> 1<span style="color: #000000">:
484 </span><span style="color: #008080">23</span>         time.sleep(random.randrange(10<span style="color: #000000">))
485 </span><span style="color: #008080">24</span>         <span style="color: #0000ff">if</span>  event.isSet(): <span style="color: #008000">#</span><span style="color: #008000">绿灯</span>
486 <span style="color: #008080">25</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">car [%s] is running..</span><span style="color: #800000">"</span> %<span style="color: #000000"> n)
487 </span><span style="color: #008080">26</span>         <span style="color: #0000ff">else</span><span style="color: #000000">:
488 </span><span style="color: #008080">27</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">car [%s] is waiting for the red light..</span><span style="color: #800000">"</span> %<span style="color: #000000">n)
489 </span><span style="color: #008080">28</span> <span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">'</span><span style="color: #800000">__main__</span><span style="color: #800000">'</span><span style="color: #000000">:
490 </span><span style="color: #008080">29</span>     event =<span style="color: #000000"> threading.Event()
491 </span><span style="color: #008080">30</span>     Light = threading.Thread(target=<span style="color: #000000">light)
492 </span><span style="color: #008080">31</span> <span style="color: #000000">    Light.start()
493 </span><span style="color: #008080">32</span>     <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(3<span style="color: #000000">):
494 </span><span style="color: #008080">33</span>         t = threading.Thread(target=car,args=<span style="color: #000000">(i,))
495 </span><span style="color: #008080">34</span>         t.start()</pre>
496 </div>
497 <span class="cnblogs_code_collapse">Event实例之红绿灯</span></div>
498 <p>这里还有一个event使用的例子,员工进公司门要刷卡, 我们这里设置一个线程是“门”, 再设置几个线程为“员工”,员工看到门没打开,就刷卡,刷完卡,门开了,员工就可以通过。</p>
499 <div class="cnblogs_code"><img id="code_img_closed_8096f152-6a5c-4c8c-8b74-3a926e5b33c5" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8096f152-6a5c-4c8c-8b74-3a926e5b33c5" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
500 <div id="cnblogs_code_open_8096f152-6a5c-4c8c-8b74-3a926e5b33c5" class="cnblogs_code_hide">
501 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">_*_coding:utf-8_*_</span>
502 <span style="color: #008080"> 2</span> <span style="color: #800080">__author__</span> = <span style="color: #800000">'</span><span style="color: #800000">Alex Li</span><span style="color: #800000">'</span>
503 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
504 </span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> time
505 </span><span style="color: #008080"> 5</span> <span style="color: #0000ff">import</span><span style="color: #000000"> random
506 </span><span style="color: #008080"> 6</span> 
507 <span style="color: #008080"> 7</span> <span style="color: #0000ff">def</span><span style="color: #000000"> door():
508 </span><span style="color: #008080"> 8</span>     door_open_time_counter =<span style="color: #000000"> 0
509 </span><span style="color: #008080"> 9</span>     <span style="color: #0000ff">while</span><span style="color: #000000"> True:
510 </span><span style="color: #008080">10</span>         <span style="color: #0000ff">if</span><span style="color: #000000"> door_swiping_event.is_set():
511 </span><span style="color: #008080">11</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[32;1mdoor opening....\033[0m</span><span style="color: #800000">"</span><span style="color: #000000">)
512 </span><span style="color: #008080">12</span>             door_open_time_counter +=1
513 <span style="color: #008080">13</span> 
514 <span style="color: #008080">14</span>         <span style="color: #0000ff">else</span><span style="color: #000000">:
515 </span><span style="color: #008080">15</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[31;1mdoor closed...., swipe to open.\033[0m</span><span style="color: #800000">"</span><span style="color: #000000">)
516 </span><span style="color: #008080">16</span>             door_open_time_counter = 0 <span style="color: #008000">#</span><span style="color: #008000">清空计时器</span>
517 <span style="color: #008080">17</span> <span style="color: #000000">            door_swiping_event.wait()
518 </span><span style="color: #008080">18</span> 
519 <span style="color: #008080">19</span> 
520 <span style="color: #008080">20</span>         <span style="color: #0000ff">if</span> door_open_time_counter &gt; 3:<span style="color: #008000">#</span><span style="color: #008000">门开了已经3s了,该关了</span>
521 <span style="color: #008080">21</span> <span style="color: #000000">            door_swiping_event.clear()
522 </span><span style="color: #008080">22</span> 
523 <span style="color: #008080">23</span>         time.sleep(0.5<span style="color: #000000">)
524 </span><span style="color: #008080">24</span> 
525 <span style="color: #008080">25</span> 
526 <span style="color: #008080">26</span> <span style="color: #0000ff">def</span><span style="color: #000000"> staff(n):
527 </span><span style="color: #008080">27</span> 
528 <span style="color: #008080">28</span>     <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">staff [%s] is comming...</span><span style="color: #800000">"</span> %<span style="color: #000000"> n )
529 </span><span style="color: #008080">29</span>     <span style="color: #0000ff">while</span><span style="color: #000000"> True:
530 </span><span style="color: #008080">30</span>         <span style="color: #0000ff">if</span><span style="color: #000000"> door_swiping_event.is_set():
531 </span><span style="color: #008080">31</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[34;1mdoor is opened, passing.....\033[0m</span><span style="color: #800000">"</span><span style="color: #000000">)
532 </span><span style="color: #008080">32</span>             <span style="color: #0000ff">break</span>
533 <span style="color: #008080">33</span>         <span style="color: #0000ff">else</span><span style="color: #000000">:
534 </span><span style="color: #008080">34</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">staff [%s] sees door got closed, swipping the card.....</span><span style="color: #800000">"</span> %<span style="color: #000000"> n)
535 </span><span style="color: #008080">35</span>             <span style="color: #0000ff">print</span><span style="color: #000000">(door_swiping_event.set())
536 </span><span style="color: #008080">36</span> <span style="color: #000000">            door_swiping_event.set()
537 </span><span style="color: #008080">37</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">after set </span><span style="color: #800000">"</span><span style="color: #000000">,door_swiping_event.set())
538 </span><span style="color: #008080">38</span>         time.sleep(0.5<span style="color: #000000">)
539 </span><span style="color: #008080">39</span> door_swiping_event  = threading.Event() <span style="color: #008000">#</span><span style="color: #008000">设置事件</span>
540 <span style="color: #008080">40</span> 
541 <span style="color: #008080">41</span> 
542 <span style="color: #008080">42</span> door_thread = threading.Thread(target=<span style="color: #000000">door)
543 </span><span style="color: #008080">43</span> <span style="color: #000000">door_thread.start()
544 </span><span style="color: #008080">44</span> 
545 <span style="color: #008080">45</span> 
546 <span style="color: #008080">46</span> 
547 <span style="color: #008080">47</span> <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(5<span style="color: #000000">):
548 </span><span style="color: #008080">48</span>     p = threading.Thread(target=staff,args=<span style="color: #000000">(i,))
549 </span><span style="color: #008080">49</span>     time.sleep(random.randrange(3<span style="color: #000000">))
550 </span><span style="color: #008080">50</span>     p.start()</pre>
551 </div>
552 <span class="cnblogs_code_collapse">event实例之刷卡</span></div>
553 <p>&nbsp;</p>
554 <p><span style="font-size: 14px"><strong>&nbsp;(6)queue队列</strong></span></p>
555 <p><span style="font-size: 14px">queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.</span></p>
556 <p>&nbsp;</p>
557 <dl class="class"><dt id="queue.Queue"><strong>class&nbsp;<code class="descclassname">queue.</code><code class="descname">Queue</code><span class="sig-paren">(maxsize=0<span class="sig-paren">) #先入先出</span></span></strong></dt><dt><strong>class&nbsp;<code class="descclassname">queue.</code><code class="descname">LifoQueue</code><span class="sig-paren">(maxsize=0<span class="sig-paren">) #last in fisrt out&nbsp;</span></span></strong></dt><dt><strong>class&nbsp;<code class="descclassname">queue.</code><code class="descname">PriorityQueue</code><span class="sig-paren">(maxsize=0<span class="sig-paren">) #存储数据时可设置优先级的队列</span></span></strong></dt><dt></dt><dt></dt></dl><dl class="method"><dt id="queue.Queue.qsize"><code class="descclassname">Queue.</code><code class="descname">qsize</code><span class="sig-paren">(<span class="sig-paren">)</span></span></dt><dt><code class="descclassname">Queue.</code><code class="descname">empty</code><span class="sig-paren">(<span class="sig-paren">) #return True if empty &nbsp;</span></span></dt><dt><code class="descclassname">Queue.</code><code class="descname">full</code><span class="sig-paren">(<span class="sig-paren">) # return True if full&nbsp;</span></span></dt><dt><span class="sig-paren"><span class="sig-paren"><code class="descclassname">Queue.</code><code class="descname">get</code><span class="sig-paren">(<em>block=True</em>,&nbsp;<em>timeout=None</em><span class="sig-paren">)</span></span></span></span></dt><dt><code class="descclassname">Queue.</code><code class="descname">put</code><span class="sig-paren">(<em>item</em>,&nbsp;<em>block=True</em>,&nbsp;<em>timeout=None</em><span class="sig-paren">)</span></span></dt><dt><span class="sig-paren"><span class="sig-paren"><code class="descclassname">Queue.</code><code class="descname">put_nowait</code><span class="sig-paren">(<em>item</em><span class="sig-paren">)</span></span></span></span></dt><dt></dt><dt><code class="descclassname">Queue.</code><code class="descname">get_nowait</code><span class="sig-paren">(<span class="sig-paren">)</span></span></dt><dt><span class="sig-paren"><code class="descclassname">Queue.</code><code class="descname">join</code><span class="sig-paren">(<span class="sig-paren">) block直到queue被消费完毕</span></span></span></dt><dt></dt><dt></dt><dt></dt></dl>
558 <p>&nbsp;a、先入先出</p>
559 <div class="cnblogs_code"><img id="code_img_closed_9c0b729a-9405-4711-8ecd-5c8043b4dc52" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9c0b729a-9405-4711-8ecd-5c8043b4dc52" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
560 <div id="cnblogs_code_open_9c0b729a-9405-4711-8ecd-5c8043b4dc52" class="cnblogs_code_hide">
561 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
562 <span style="color: #008080"> 2</span> 
563 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> queue
564 </span><span style="color: #008080"> 4</span> q =<span style="color: #000000">queue.Queue()
565 </span><span style="color: #008080"> 5</span> 
566 <span style="color: #008080"> 6</span> q.put(1<span style="color: #000000">)
567 </span><span style="color: #008080"> 7</span> q.put(2<span style="color: #000000">)
568 </span><span style="color: #008080"> 8</span> q.put(3<span style="color: #000000">)
569 </span><span style="color: #008080"> 9</span> 
570 <span style="color: #008080">10</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.qsize())
571 </span><span style="color: #008080">11</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
572 </span><span style="color: #008080">12</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
573 </span><span style="color: #008080">13</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
574 </span><span style="color: #008080">14</span> <span style="color: #008000">#</span><span style="color: #008000">先入先出,这个时候如果在获取呢?就会挂起卡死</span>
575 <span style="color: #008080">15</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
576 </span><span style="color: #008080">16</span> <span style="color: #008000">#</span><span style="color: #008000">在这里看不出来什么效果。去命令行试试</span></pre>
577 </div>
578 <span class="cnblogs_code_collapse">先入先出</span></div>
579 <p><img src="https://images2018.cnblogs.com/blog/1435523/201809/1435523-20180903141516230-1658960823.png" alt=""></p>
580 <p>存在一个问题就是,当把所有的数据都get到之后,程序就会挂起卡死。那这个时候怎么办呢?</p>
581 <p>q.get_nowait() &nbsp;或者通过get(block=True,Timeout)参数进行设置</p>
582 <p>会出现先一个queue Empty的异常,这个时候可以通过捕获异常使程序正常进行。</p>
583 <p><img src="https://images2018.cnblogs.com/blog/1435523/201809/1435523-20180903141732769-380682019.png" alt=""></p>
584 <p><img src="https://images2018.cnblogs.com/blog/1435523/201809/1435523-20180903142118901-1628911451.png" alt=""></p>
585 <p><img src="https://images2018.cnblogs.com/blog/1435523/201809/1435523-20180903142153407-430380383.png" alt=""></p>
586 <p>&nbsp;</p>
587 <p>b、后进先出</p>
588 <div class="cnblogs_code"><img id="code_img_closed_57672cd1-85fa-4509-a13d-781b91ae2351" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_57672cd1-85fa-4509-a13d-781b91ae2351" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
589 <div id="cnblogs_code_open_57672cd1-85fa-4509-a13d-781b91ae2351" class="cnblogs_code_hide">
590 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
591 <span style="color: #008080"> 2</span> 
592 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> queue
593 </span><span style="color: #008080"> 4</span> q =<span style="color: #000000">queue.LifoQueue()
594 </span><span style="color: #008080"> 5</span> q.put(1<span style="color: #000000">)
595 </span><span style="color: #008080"> 6</span> q.put(2<span style="color: #000000">)
596 </span><span style="color: #008080"> 7</span> q.put(3<span style="color: #000000">)
597 </span><span style="color: #008080"> 8</span> 
598 <span style="color: #008080"> 9</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.qsize())
599 </span><span style="color: #008080">10</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
600 </span><span style="color: #008080">11</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
601 </span><span style="color: #008080">12</span> <span style="color: #0000ff">print</span>(q.get())</pre>
602 </div>
603 <span class="cnblogs_code_collapse">后进先出LifoQueue</span></div>
604 <p>c、设置优先级</p>
605 <div class="cnblogs_code"><img id="code_img_closed_d61f3381-175d-4842-82ab-e947705523a2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_d61f3381-175d-4842-82ab-e947705523a2" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
606 <div id="cnblogs_code_open_d61f3381-175d-4842-82ab-e947705523a2" class="cnblogs_code_hide">
607 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
608 <span style="color: #008080"> 2</span> 
609 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> queue
610 </span><span style="color: #008080"> 4</span> 
611 <span style="color: #008080"> 5</span> q =<span style="color: #000000">queue.PriorityQueue()
612 </span><span style="color: #008080"> 6</span> q.put((1,<span style="color: #800000">"</span><span style="color: #800000">erha</span><span style="color: #800000">"</span><span style="color: #000000">))
613 </span><span style="color: #008080"> 7</span> q.put((5,<span style="color: #800000">"</span><span style="color: #800000">hashiqi</span><span style="color: #800000">"</span><span style="color: #000000">))
614 </span><span style="color: #008080"> 8</span> q.put((3,<span style="color: #800000">"</span><span style="color: #800000">taidi</span><span style="color: #800000">"</span><span style="color: #000000">))
615 </span><span style="color: #008080"> 9</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
616 </span><span style="color: #008080">10</span> <span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
617 </span><span style="color: #008080">11</span> <span style="color: #0000ff">print</span>(q.get())</pre>
618 </div>
619 <span class="cnblogs_code_collapse">优先级队列</span></div>
620 <p>&nbsp;</p>
621 <p>下面以一个生产者消费者的模型实例来深刻体会一下队列。</p>
622 <div class="cnblogs_code"><img id="code_img_closed_b57c3665-dcb9-4f96-aa10-61b107d20eb2" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b57c3665-dcb9-4f96-aa10-61b107d20eb2" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
623 <div id="cnblogs_code_open_b57c3665-dcb9-4f96-aa10-61b107d20eb2" class="cnblogs_code_hide">
624 <pre><span style="color: #0000ff">import</span><span style="color: #000000"> threading
625 </span><span style="color: #0000ff">import</span><span style="color: #000000"> queue
626  
627 </span><span style="color: #0000ff">def</span><span style="color: #000000"> producer():
628     </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(10<span style="color: #000000">):
629         q.put(</span><span style="color: #800000">"</span><span style="color: #800000">baozi %s</span><span style="color: #800000">"</span> %<span style="color: #000000"> i )
630  
631     </span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">开始等待所有的包子被取走...</span><span style="color: #800000">"</span><span style="color: #000000">)
632     q.join()
633     </span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">所有的包子被取完了...</span><span style="color: #800000">"</span><span style="color: #000000">)
634  
635  
636 </span><span style="color: #0000ff">def</span><span style="color: #000000"> consumer(n):
637  
638     </span><span style="color: #0000ff">while</span> q.qsize() &gt;<span style="color: #000000">0:
639  
640         </span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">%s 取到</span><span style="color: #800000">"</span> %<span style="color: #000000">n  , q.get())
641         q.task_done() </span><span style="color: #008000">#</span><span style="color: #008000">告知这个任务执行完了</span>
642 <span style="color: #000000"> 
643  
644 q </span>=<span style="color: #000000"> queue.Queue()
645  
646  
647  
648 p </span>= threading.Thread(target=<span style="color: #000000">producer,)
649 p.start()
650  
651 c1 </span>= consumer(<span style="color: #800000">"</span><span style="color: #800000">二哈</span><span style="color: #800000">"</span>)</pre>
652 </div>
653 <span class="cnblogs_code_collapse">生产者消费者模型1</span></div>
654 <div class="cnblogs_code"><img id="code_img_closed_dd068d45-d0fe-4147-9ad3-fe9cd3ec2eb4" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_dd068d45-d0fe-4147-9ad3-fe9cd3ec2eb4" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
655 <div id="cnblogs_code_open_dd068d45-d0fe-4147-9ad3-fe9cd3ec2eb4" class="cnblogs_code_hide">
656 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">Author:ZhangKanghui</span>
657 <span style="color: #008080"> 2</span> 
658 <span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading,time
659 </span><span style="color: #008080"> 4</span> <span style="color: #0000ff">import</span><span style="color: #000000"> queue
660 </span><span style="color: #008080"> 5</span> 
661 <span style="color: #008080"> 6</span> q =<span style="color: #000000"> queue.Queue()
662 </span><span style="color: #008080"> 7</span> <span style="color: #0000ff">def</span><span style="color: #000000"> Producer(namne):
663 </span><span style="color: #008080"> 8</span>     count =<span style="color: #000000"> 0
664 </span><span style="color: #008080"> 9</span>     <span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(10<span style="color: #000000">):
665 </span><span style="color: #008080">10</span>         q.put(<span style="color: #800000">"</span><span style="color: #800000">骨头%s</span><span style="color: #800000">"</span>%<span style="color: #000000">count)
666 </span><span style="color: #008080">11</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">生产了骨头</span><span style="color: #800000">"</span><span style="color: #000000">,count)
667 </span><span style="color: #008080">12</span>         count +=1
668 <span style="color: #008080">13</span>         <span style="color: #008000">#</span><span style="color: #008000">time.sleep(2)</span>
669 <span style="color: #008080">14</span>         time.sleep(1<span style="color: #000000">)
670 </span><span style="color: #008080">15</span>         <span style="color: #008000">#</span><span style="color: #008000">time.sleep(0.5)</span>
671 <span style="color: #008080">16</span> 
672 <span style="color: #008080">17</span> <span style="color: #0000ff">def</span><span style="color: #000000"> Consumer(name):
673 </span><span style="color: #008080">18</span>     <span style="color: #0000ff">while</span><span style="color: #000000"> True:
674 </span><span style="color: #008080">19</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">[%s] 取到 [%s] 并吃了它...</span><span style="color: #800000">"</span>%<span style="color: #000000">(name,q.get()))
675 </span><span style="color: #008080">20</span> 
676 <span style="color: #008080">21</span> p =threading.Thread(target=Producer,args=(<span style="color: #800000">"</span><span style="color: #800000">Kanghui</span><span style="color: #800000">"</span><span style="color: #000000">,))
677 </span><span style="color: #008080">22</span> c =threading.Thread(target=Consumer,args=(<span style="color: #800000">"</span><span style="color: #800000">erha</span><span style="color: #800000">"</span><span style="color: #000000">,))
678 </span><span style="color: #008080">23</span> c1 =threading.Thread(target=Consumer,args=(<span style="color: #800000">"</span><span style="color: #800000">taidi</span><span style="color: #800000">"</span><span style="color: #000000">,))
679 </span><span style="color: #008080">24</span> 
680 <span style="color: #008080">25</span> <span style="color: #000000">p.start()
681 </span><span style="color: #008080">26</span> <span style="color: #000000">c.start()
682 </span><span style="color: #008080">27</span> c1.start()</pre>
683 </div>
684 <span class="cnblogs_code_collapse">生产者消费者模型2</span></div>
685 <p>&nbsp;</p>
686 <blockquote>
687 <p><span style="font-size: 14pt"><strong>4 小结</strong></span></p>
688 </blockquote>
689 <p>志不坚者智不达。</p>
690 <p>撑不住的时候可以对自己说声“我好累”,但永远不要再心里承认“我不行”。</p>
691 <p>没有鸡汤就没有生活。</p>
692 <p>&nbsp;</p>
693 <blockquote>
694 <p><span style="font-size: 14pt"><strong>5 练习</strong></span></p>
695 </blockquote>
696 <p>需求:</p>
697 <ol>
698 <li>主机分组</li>
699 <li>登录后显示主机分组,选择分组后查看主机列表</li>
700 <li>可批量执行命令、发送文件,结果实时返回</li>
701 <li>主机用户名密码可以不同</li>
702 </ol>
703 <p>&nbsp;</p>
704 <p><strong>流程图:</strong></p>
705 <p><strong><img src="https://images2018.cnblogs.com/blog/1435523/201809/1435523-20180903145959431-1674715659.png" alt=""></strong></p>
706 <p>&nbsp;</p>
707 <div class="cnblogs_code"><img id="code_img_closed_cd6358f5-8a69-4ab5-9c67-cdf1ca5f7216" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_cd6358f5-8a69-4ab5-9c67-cdf1ca5f7216" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
708 <div id="cnblogs_code_open_cd6358f5-8a69-4ab5-9c67-cdf1ca5f7216" class="cnblogs_code_hide">
709 <pre><span style="color: #008080"> 1</span> <span style="color: #008000">#</span><span style="color: #008000">## 作者介绍:</span>
710 <span style="color: #008080"> 2</span> *<span style="color: #000000"> author:lzl
711 </span><span style="color: #008080"> 3</span> <span style="color: #008000">#</span><span style="color: #008000">## 博客地址:</span>
712 <span style="color: #008080"> 4</span> * http://www.cnblogs.com/lianzhilei/p/5881434<span style="color: #000000">.html
713 </span><span style="color: #008080"> 5</span> 
714 <span style="color: #008080"> 6</span> <span style="color: #008000">#</span><span style="color: #008000">## 功能实现</span>
715 <span style="color: #008080"> 7</span> <span style="color: #000000">题目:简单主机批量管理工具
716 </span><span style="color: #008080"> 8</span> 
717 <span style="color: #008080"> 9</span> <span style="color: #000000">    需求:
718 </span><span style="color: #008080">10</span> <span style="color: #000000">    主机分组
719 </span><span style="color: #008080">11</span> <span style="color: #000000">    登录后显示主机分组,选择分组后查看主机列表
720 </span><span style="color: #008080">12</span> <span style="color: #000000">    可批量执行命令、发送文件,结果实时返回
721 </span><span style="color: #008080">13</span> <span style="color: #000000">    主机用户名密码可以不同
722 </span><span style="color: #008080">14</span> 
723 <span style="color: #008080">15</span> <span style="color: #008000">#</span><span style="color: #008000">## 目录结构:</span>
724 <span style="color: #008080">16</span>     Host-<span style="color: #000000">Manage
725 </span><span style="color: #008080">17</span> <span style="color: #000000">726 </span><span style="color: #008080">18</span>     ├── ftpclient <span style="color: #008000">#</span><span style="color: #008000">客户端程序</span>
727 <span style="color: #008080">19</span> <span style="color: #000000">            ├── README.txt
728 </span><span style="color: #008080">20</span>             ├── management.py <span style="color: #008000">#</span><span style="color: #008000">服务端入口程序</span>
729 <span style="color: #008080">21</span>             ├── database <span style="color: #008000">#</span><span style="color: #008000">数据库</span>
730 <span style="color: #008080">22</span>             ├── test.py <span style="color: #008000">#</span><span style="color: #008000">修改数据库</span>
731 <span style="color: #008080">23</span> 
732 <span style="color: #008080">24</span> 
733 <span style="color: #008080">25</span> <span style="color: #008000">#</span><span style="color: #008000">## 注释</span>
734 <span style="color: #008080">26</span> <span style="color: #000000">    可批量执行命令、发送文件
735 </span><span style="color: #008080">27</span>     上传命令格式: put database /tmp/<span style="color: #000000">db
736 </span><span style="color: #008080">28</span> 
737 <span style="color: #008080">29</span> 
738 <span style="color: #008080">30</span> <span style="color: #008000">#</span><span style="color: #008000">## 运行环境</span>
739 <span style="color: #008080">31</span> <span style="color: #000000">    windows系统
740 </span><span style="color: #008080">32</span>     python3.0+
741 <span style="color: #008080">33</span> 
742 <span style="color: #008080">34</span> README</pre>
743 </div>
744 <span class="cnblogs_code_collapse">Readme</span></div>
745 <div class="cnblogs_code"><img id="code_img_closed_95a7ee23-0f9a-46de-abb4-283ec9bcbda9" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_95a7ee23-0f9a-46de-abb4-283ec9bcbda9" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
746 <div id="cnblogs_code_open_95a7ee23-0f9a-46de-abb4-283ec9bcbda9" class="cnblogs_code_hide">
747 <pre><span style="color: #008080"> 1</span> <span style="color: #0000ff">import</span><span style="color: #000000"> json
748 </span><span style="color: #008080"> 2</span> <span style="color: #0000ff">import</span><span style="color: #000000"> paramiko
749 </span><span style="color: #008080"> 3</span> <span style="color: #0000ff">import</span><span style="color: #000000"> threading
750 </span><span style="color: #008080"> 4</span>  
751 <span style="color: #008080"> 5</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Remotehost(object):
752 </span><span style="color: #008080"> 6</span>     <span style="color: #008000">#</span><span style="color: #008000">远程操作主机</span>
753 <span style="color: #008080"> 7</span>     <span style="color: #0000ff">def</span> <span style="color: #800080">__init__</span><span style="color: #000000">(self,host,port,username,password,cmd):
754 </span><span style="color: #008080"> 8</span>         self.host =<span style="color: #000000"> host
755 </span><span style="color: #008080"> 9</span>         self.port =<span style="color: #000000"> port
756 </span><span style="color: #008080">10</span>         self.username =<span style="color: #000000"> username
757 </span><span style="color: #008080">11</span>         self.password =<span style="color: #000000"> password
758 </span><span style="color: #008080">12</span>         self.cmd =<span style="color: #000000"> cmd
759 </span><span style="color: #008080">13</span>  
760 <span style="color: #008080">14</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> command(self):
761 </span><span style="color: #008080">15</span>         <span style="color: #008000">#</span><span style="color: #008000">获取命令</span>
762 <span style="color: #008080">16</span>         ssh =<span style="color: #000000"> paramiko.SSHClient()
763 </span><span style="color: #008080">17</span>         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())   <span style="color: #008000">#</span><span style="color: #008000"> 允许连接不在know_hosts文件中的主机</span>
764 <span style="color: #008080">18</span>         ssh.connect(hostname=self.host, port=self.port, username=self.username, password=self.password)   <span style="color: #008000">#</span><span style="color: #008000"> 连接服务器</span>
765 <span style="color: #008080">19</span>         stdin, stdout, stderr = ssh.exec_command(self.cmd)              <span style="color: #008000">#</span><span style="color: #008000"> 获取命令结果</span>
766 <span style="color: #008080">20</span>         res ,err = stdout.read(),stderr.read()              <span style="color: #008000">#</span><span style="color: #008000"> 三元运算</span>
767 <span style="color: #008080">21</span>         result = res <span style="color: #0000ff">if</span> res <span style="color: #0000ff">else</span><span style="color: #000000"> err
768 </span><span style="color: #008080">22</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">[%s]</span><span style="color: #800000">"</span>.center(50,<span style="color: #800000">"</span><span style="color: #800000">-</span><span style="color: #800000">"</span>)%<span style="color: #000000">self.host)
769 </span><span style="color: #008080">23</span>         <span style="color: #0000ff">print</span>(result.decode())                                      <span style="color: #008000">#</span><span style="color: #008000"> 打印输出</span>
770 <span style="color: #008080">24</span> <span style="color: #000000">        ssh.close()
771 </span><span style="color: #008080">25</span>  
772 <span style="color: #008080">26</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> put(self):
773 </span><span style="color: #008080">27</span>         <span style="color: #008000">#</span><span style="color: #008000">上传</span>
774 <span style="color: #008080">28</span>         <span style="color: #0000ff">try</span><span style="color: #000000">:
775 </span><span style="color: #008080">29</span>             transport =<span style="color: #000000"> paramiko.Transport((self.host, self.port))
776 </span><span style="color: #008080">30</span>             transport.connect(username=self.username, password=<span style="color: #000000">self.password)
777 </span><span style="color: #008080">31</span>             sftp =<span style="color: #000000"> paramiko.SFTPClient.from_transport(transport)
778 </span><span style="color: #008080">32</span>             sftp.put(self.cmd.split()[1], self.cmd.split()[2])              <span style="color: #008000">#</span><span style="color: #008000"> 上传文件</span>
779 <span style="color: #008080">33</span> <span style="color: #000000">            transport.close()
780 </span><span style="color: #008080">34</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[32;0m【%s】 上传 文件【%s】 成功....\033[0m</span><span style="color: #800000">"</span>%(self.host,self.cmd.split()[2<span style="color: #000000">]))
781 </span><span style="color: #008080">35</span>         <span style="color: #0000ff">except</span> Exception as error:                                <span style="color: #008000">#</span><span style="color: #008000"> 抓住异常</span>
782 <span style="color: #008080">36</span>             <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[31;0m错误:【%s】【%s】\033[0m</span><span style="color: #800000">"</span>%<span style="color: #000000">(self.host,error))
783 </span><span style="color: #008080">37</span>  
784 <span style="color: #008080">38</span>     <span style="color: #0000ff">def</span><span style="color: #000000"> run(self):
785 </span><span style="color: #008080">39</span>         <span style="color: #008000">#</span><span style="color: #008000">反射</span>
786 <span style="color: #008080">40</span>         cmd_str =<span style="color: #000000"> self.cmd.split()[0]
787 </span><span style="color: #008080">41</span>         <span style="color: #0000ff">if</span><span style="color: #000000"> hasattr(self,cmd_str):
788 </span><span style="color: #008080">42</span> <span style="color: #000000">            getattr(self,cmd_str)()
789 </span><span style="color: #008080">43</span>         <span style="color: #0000ff">else</span><span style="color: #000000">:
790 </span><span style="color: #008080">44</span> <span style="color: #000000">            setattr(self,cmd_str,self.command)
791 </span><span style="color: #008080">45</span> <span style="color: #000000">            getattr(self,cmd_str)()
792 </span><span style="color: #008080">46</span>  
793 <span style="color: #008080">47</span>  
794 <span style="color: #008080">48</span> <span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">"</span><span style="color: #800000">__main__</span><span style="color: #800000">"</span><span style="color: #000000">:
795 </span><span style="color: #008080">49</span>     <span style="color: #008000">#</span><span style="color: #008000">主程序</span>
796 <span style="color: #008080">50</span>     with open(<span style="color: #800000">"</span><span style="color: #800000">database</span><span style="color: #800000">"</span>,<span style="color: #800000">"</span><span style="color: #800000">r</span><span style="color: #800000">"</span><span style="color: #000000">) as file:
797 </span><span style="color: #008080">51</span>         data_dict = json.loads(file.read())     <span style="color: #008000">#</span><span style="color: #008000">获取数据库信息</span>
798 <span style="color: #008080">52</span>     <span style="color: #0000ff">for</span> k <span style="color: #0000ff">in</span> data_dict:                        <span style="color: #008000">#</span><span style="color: #008000">打印地址组</span>
799 <span style="color: #008080">53</span>         <span style="color: #0000ff">print</span><span style="color: #000000">(k)
800 </span><span style="color: #008080">54</span>  
801 <span style="color: #008080">55</span>     group_choice = input(<span style="color: #800000">"</span><span style="color: #800000">输入要操作的组名:</span><span style="color: #800000">"</span><span style="color: #000000">).strip()
802 </span><span style="color: #008080">56</span>     <span style="color: #0000ff">if</span><span style="color: #000000"> data_dict.get(group_choice):
803 </span><span style="color: #008080">57</span>         host_dict = data_dict[group_choice]     <span style="color: #008000">#</span><span style="color: #008000">定义主机字典</span>
804 <span style="color: #008080">58</span>         <span style="color: #0000ff">for</span> k <span style="color: #0000ff">in</span> host_dict:                    <span style="color: #008000">#</span><span style="color: #008000">打印所选地址组所有的主机名</span>
805 <span style="color: #008080">59</span>             <span style="color: #0000ff">print</span><span style="color: #000000">(k)
806 </span><span style="color: #008080">60</span>         <span style="color: #0000ff">while</span><span style="color: #000000"> True:
807 </span><span style="color: #008080">61</span>             cmd = input(<span style="color: #800000">"</span><span style="color: #800000">选择进行的操作的命令:</span><span style="color: #800000">"</span><span style="color: #000000">).strip()
808 </span><span style="color: #008080">62</span>             thread_list=<span style="color: #000000">[]
809 </span><span style="color: #008080">63</span>             <span style="color: #0000ff">if</span> cmd:                                 <span style="color: #008000">#</span><span style="color: #008000">命令不为空</span>
810 <span style="color: #008080">64</span>                 <span style="color: #0000ff">for</span> k <span style="color: #0000ff">in</span><span style="color: #000000"> host_dict:
811 </span><span style="color: #008080">65</span>                     host, port, username, password=k,host_dict[k][<span style="color: #800000">"</span><span style="color: #800000">port</span><span style="color: #800000">"</span>],host_dict[k][<span style="color: #800000">"</span><span style="color: #800000">username</span><span style="color: #800000">"</span>],host_dict[k][<span style="color: #800000">"</span><span style="color: #800000">password</span><span style="color: #800000">"</span><span style="color: #000000">]
812 </span><span style="color: #008080">66</span>                     func = Remotehost(host,port,username,password,cmd)      <span style="color: #008000">#</span><span style="color: #008000">实例化类</span>
813 <span style="color: #008080">67</span>                     t = threading.Thread(target=func.run)                   <span style="color: #008000">#</span><span style="color: #008000">创建线程</span>
814 <span style="color: #008080">68</span> <span style="color: #000000">                    t.start()
815 </span><span style="color: #008080">69</span> <span style="color: #000000">                    thread_list.append(t)
816 </span><span style="color: #008080">70</span>                 <span style="color: #0000ff">for</span> t <span style="color: #0000ff">in</span><span style="color: #000000"> thread_list:
817 </span><span style="color: #008080">71</span>                     t.join()                                                <span style="color: #008000">#</span><span style="color: #008000">等待线程执行结果</span>
818 <span style="color: #008080">72</span>     <span style="color: #0000ff">else</span><span style="color: #000000">:
819 </span><span style="color: #008080">73</span>         <span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">\033[31;0m操作组不存在\033[0m</span><span style="color: #800000">"</span>)</pre>
820 </div>
821 <span class="cnblogs_code_collapse">简单主机批量管理工具主程序</span></div>
822 <p>相关参考:<a href="https://www.cnblogs.com/0zcl/p/6352278.html" target="_blank">https://www.cnblogs.com/0zcl/p/6352278.html</a></p>
823 <p>&nbsp;</p>
824 <p>&nbsp;</p>
825 <p><strong>我是尾巴~</strong></p>
826 <p>这次推荐:摄影app合集  <a href="https://mp.weixin.qq.com/s/3N3m7otgKIZXGyUpGKbTpw" target="_blank">https://mp.weixin.qq.com/s/3N3m7otgKIZXGyUpGKbTpw</a></p>
827 <p>虽不才,才要坚持。</p></div><div id="MySignature"></div>
828 <div class="clear"></div>
829 <div id="blog_post_info_block">
830 <div id="BlogPostCategory"></div>
831 <div id="EntryTag"></div>
832 <div id="blog_post_info">
833 </div>
834 <div class="clear"></div>
835 <div id="post_next_prev"></div>
836 </div>
837 
838 
839         </div>
840         <div class = "postDesc">posted @ <span id="post-date">2018-09-03 15:09</span> <a href='https://www.cnblogs.com/zhangkanghui/'>m1racle</a> 阅读(<span id="post_view_count">...</span>) 评论(<span id="post_comment_count">...</span>)  <a href ="https://i.cnblogs.com/EditPosts.aspx?postid=9577714" rel="nofollow">编辑</a> <a href="#" onclick="AddToWz(9577714);return false;">收藏</a></div>
841     </div>
842     <script type="text/javascript">var allowComments=true,cb_blogId=442473,cb_entryId=9577714,cb_blogApp=currentBlogApp,cb_blogUserGuid='a821bb9d-4d70-4e51-5253-08d5ddce222f',cb_entryCreatedDate='2018/9/3 15:09:00';loadViewCount(cb_entryId);var cb_postType=1;</script>
843     
844 </div><!--end: topics 文章、评论容器-->
845 </div><a name="!comments"></a><div id="blog-comments-placeholder"></div><script type="text/javascript">var commentManager = new blogCommentManager();commentManager.renderComments(0);</script>
846 <div id='comment_form' class='commentform'>
847 <a name='commentform'></a>
848 <div id='divCommentShow'></div>
849 <div id='comment_nav'><span id='span_refresh_tips'></span><a href='javascript:void(0);' onclick='return RefreshCommentList();' id='lnk_RefreshComments' runat='server' clientidmode='Static'>刷新评论</a><a href='#' onclick='return RefreshPage();'>刷新页面</a><a href='#top'>返回顶部</a></div>
850 <div id='comment_form_container'></div>
851 <div class='ad_text_commentbox' id='ad_text_under_commentbox'></div>
852 <div id='ad_t2'></div>
853 <div id='opt_under_post'></div>
854 <div id='cnblogs_c1' class='c_ad_block'></div>
855 <div id='under_post_news'></div>
856 <div id='cnblogs_c2' class='c_ad_block'></div>
857 <div id='under_post_kb'></div>
858 <div id='HistoryToday' class='c_ad_block'></div>
859 <script type='text/javascript'>
860     fixPostBody();
861     setTimeout(function () { incrementViewCount(cb_entryId); }, 50);
862     deliverAdT2();
863     deliverAdC1();
864     deliverAdC2();    
865     loadNewsAndKb();
866     loadBlogSignature();
867     LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
868     GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
869     loadOptUnderPost();
870     GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);   
871 </script>
872 </div>
873 
874 
875     </div><!--end: forFlow -->
876     </div><!--end: mainContent 主体内容容器-->
877 
878     <div id="sideBar">
879         <div id="sideBarMain">
880             
881 <!--done-->
882 <div class="newsItem">
883 <h3 class="catListTitle">公告</h3>
884     <div id="blog-news"></div><script type="text/javascript">loadBlogNews();</script>
885 </div>
886 
887             <div id="blog-calendar" style="display:none"></div><script type="text/javascript">loadBlogDefaultCalendar();</script>
888             
889             <div id="leftcontentcontainer">
890                 <div id="blog-sidecolumn"></div><script type="text/javascript">loadBlogSideColumn();</script>
891             </div>
892             
893         </div><!--end: sideBarMain -->
894     </div><!--end: sideBar 侧边栏容器 -->
895     <div class="clear"></div>
896     </div><!--end: main -->
897     <div class="clear"></div>
898     <div id="footer">
899         
900 <!--done-->
901 Copyright &copy;2018 m1racle
902     </div><!--end: footer -->
903 </div><!--end: home 自定义的最大容器 -->
904 </body>
905 </html>
来看看爬到了什么

如果同时爬多个网站呢?

 1 #Author:ZhangKanghui
 2 
 3 from urllib import request
 4 import gevent
 5 import time
 6 from gevent import monkey
 7 #它的作用就是把当前程序的所有io操作单独做上标记
 8 monkey.patch_all()      #试一下有它没它的区别
 9 
10 def f(url):
11     print("GET:%s"%url)
12     resp = request.urlopen(url)
13     data = resp.read()
14     print("%d bytes received from %s."%(len(data),url))
15 
16 urls = ["https://www.yahoo.com/",
17         "https://www.python.org/",
18         "https://www.github.com/",
19 ]
20 time_start = time.time()
21 for url in urls:
22     f(url)
23 print("同步cost:",time.time() - time_start)
24 
25 aysnc_time_start = time.time()
26 gevent.joinall(
27     [gevent.spawn(f,"https://www.yahoo.com/"),
28      gevent.spawn(f,"https://www.python.org/"),
29      gevent.spawn(f,"https://www.github.com/"),
30 ])
31 print("异步cost:",time.time() - aysnc_time_start)
爬虫gevent

如果想对爬虫进入深入的了解和学习,可以参考这里:

https://www.cnblogs.com/voidking/p/python-crawler-base.html

 

3 select

select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。

select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一。

select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。

另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销。

如果想深入了解和学习select、poll、epoll三者的区别,看这里:

http://www.cnblogs.com/alex3714/p/4372426.html

通过select实现socket多并发

 1 #Author:ZhangKanghui
 2 
 3 import select
 4 import socket
 5 import sys
 6 import queue
 7 
 8 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 9 server.bind(('local host',9000))
10 server.listen(1000)
11 
12 server.setblocking(False)
13 
14 msg_dict = []
15 inputs = [server,]
16 outputs = []
17 while True:
18     readable ,writerable ,exceptional = select.select(inputs,outputs,inputs)
19     print(readable,writerable,exceptional)
20     for i in readable:
21         if r is server:
22             conn,addr = server.accept()
23             print("new connection is coming")
24             print(conn,addr)
25             inputs.append(conn)    #是因为这个新建立的链接还没发数据过来,现在接受的话程序就报错
26             #所以要实现这个客户端发数据来时server端能知道,就需要让select再监测
27             msg_dict [conn] =queue.Queue()      #初始化一个队列,后面存要给客户端返回的数据
28         else:
29             data = r.recv(1024)
30             # print("recv:",data)
31             # print("send done....")
32             #如果不想立马把数据传给客户端可以这么干
33             msg_dict[r].put(data)
34             outputs.append(r)       #放入返回的连接队列里
35 
36     for w in writerable:    #要返回客户端的连接列表
37         data_to_client = msg_dict[w].get()
38         w.send(data_to_client)
39         outputs.reverse(w)      #确保下次循环的时候writerable不返回已经处理完的连接
40 
41     for e in exceptional:
42         if e in outputs:
43             outputs.remove(e)
44 
45         inputs.remove(e)
46 
47         del msg_dict[e]
通过select实现socket多并发
 1 import socket
 2 import sys
 3 
 4 messages = [ b'This is the message. ',
 5              b'It will be sent ',
 6              b'in parts.',
 7              ]
 8 server_address = ('localhost', 10000)
 9 
10 # Create a TCP/IP socket
11 socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
12           socket.socket(socket.AF_INET, socket.SOCK_STREAM),
13           ]
14 
15 # Connect the socket to the port where the server is listening
16 print('connecting to %s port %s' % server_address)
17 for s in socks:
18     s.connect(server_address)
19 
20 for message in messages:
21 
22     # Send messages on both sockets
23     for s in socks:
24         print('%s: sending "%s"' % (s.getsockname(), message) )
25         s.send(message)
26 
27     # Read responses on both sockets
28     for s in socks:
29         data = s.recv(1024)
30         print( '%s: received "%s"' % (s.getsockname(), data) )
31         if not data:
32             print(sys.stderr, 'closing socket', s.getsockname() )
select_socket_client

 

selectors模块

This module allows high-level and efficient I/O multiplexing, built upon the select module primitives.

Users are encouraged to use this module instead, unless they want precise control over the OS-level primitives used.

 1 #Author:ZhangKanghui
 2 
 3 import selectors
 4 import socket
 5 
 6 sel = selectors.DefaultSelector()
 7 
 8 def accept(sock,mask):
 9     conn,addr = sock.accept()
10     print("accept",conn,"from",addr,mask)
11     conn.setblocking(False)
12     sel.register(conn,selectors.EVENT_READ,read)
13 
14 def read(conn,mask):
15     data = conn.recv(1024)
16     if data:
17         print("echoing",repr(data),'to',conn)
18         conn.send(data)
19     else:
20         print("closing",conn)
21         sel.unregister(conn)
22         conn.close()
23 
24 sock = socket.socket()
25 sock.bind('localhosr',9999)
26 sock.listen(100)
27 sock.setblocking(False)
28 sel.register(sock,selectors.EVENT_READ,accept)
29 
30 while True:
31     events = sel.select()
32     for key,mask in events:
33         callback = key.data
34         callback(key.fileobj,mask)
selector

 

4 IO多路复用

同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?

是真的不懂,看这个吧:

http://www.cnblogs.com/alex3714/articles/5876749.html

 

5 小结

这些计算机方面的东西太深入了,有点懵逼,实现不知道怎么写下去了

这一节就这样吧!以后再慢慢补充

别的不确定,但是爬虫的部分以后应该会有后续。

 

6 练习

这次没有作业

给出一个支持向量机的算法:

 1 #Author:ZhangKanghui
 2 
 3 from sklearn import svm
 4 
 5 x =[[2,0],[1,1],[2,3]]
 6 y =[0,0,1]
 7 clf =svm.SVC(kernel = "linear")
 8 print(clf)
 9 clf.fit(x,y)
10 #打印支持向量点
11 print(clf.support_vectors_)
12 #打印支持向量点的索引值index
13 print(clf.support_)
14 #两个类里面分别有1个支持向量
15 print(clf.n_support_)
16 print(clf.predict([[2,0],[2,-1]]))
17 
18 
19 '''
20 print(clf.predict([2,0]))
21 不知道问什么这样会有一个一个警告
22 DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. 
23 Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.
24 DeprecationWarning)
25 '''
SVM

还有进阶版的!

 1 #Author:ZhangKanghui
 2 print(__doc__)
 3 
 4 #numpy是python中支持矩阵运算的一个模块
 5 #pylab画图
 6 import numpy as np
 7 import pylab as pl
 8 from sklearn import svm
 9 
10 np.random.seed(0)
11 X =np.r_[np.random.randn(20,2)-[2,2],np.random.rand(20,2)+[2,2]]
12 # print(X)
13 Y =[0]*20+[1]*20
14 # print(Y)
15 
16 clf =svm.SVC(kernel="linear")
17 clf.fit(X,Y)
18 
19 w =clf.coef_[0]
20 a = -w[0] / w[1]
21 xx = np.linspace(-5,5)
22 yy = a*xx - (clf.intercept_[0]) / w[1]
23 
24 b = clf.support_vectors_[0]
25 yy_down = a*xx + (b[1] - a *b[0])
26 b = clf.support_vectors_[-1]
27 yy_up = a*xx +(b[1] - a *b[0])
28 
29 pl.plot(xx,yy,"")
30 pl.plot(xx,yy_down,"")
31 pl.plot(xx,yy_up,"")\
32 
33 pl.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=80)
34 pl.scatter(X[:,0],X[:,1],c=Y,cmap=pl.cm.paired)
35 
36 pl.axis("tight")
37 print(pl.show())
SVM进阶版

 

 

我是尾巴~

这次推荐:Scien公布的125个科学前沿问题:https://mp.weixin.qq.com/s/0oK1VWvuiS2znYqOQJQdMg

虽不才,才要坚持!