s12-20160312-day09

*:first-child {
margin-top: 0 !important;
}

body>*:last-child {
margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
font-size: inherit;
}

h1 {
font-size: 28px;
color: #000;
}

h2 {
font-size: 24px;
border-bottom: 1px solid #ccc;
color: #000;
}

h3 {
font-size: 18px;
}

h4 {
font-size: 16px;
}

h5 {
font-size: 14px;
}

h6 {
color: #777;
font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
margin-top: 0;
padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
color: #4183C4;
text-decoration: none;
}

a:hover {
text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
padding-left: 30px;
}

ul li > :first-child,
ol li > :first-child,
ul li ul:first-of-type,
ol li ol:first-of-type,
ul li ol:first-of-type,
ol li ul:first-of-type {
margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
margin-bottom: 0;
}

dl {
padding: 0;
}

dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px;
}

dl dt:first-child {
padding: 0;
}

dl dt>:first-child {
margin-top: 0px;
}

dl dt>:last-child {
margin-bottom: 0px;
}

dl dd {
margin: 0 0 15px;
padding: 0 15px;
}

dl dd>:first-child {
margin-top: 0px;
}

dl dd>:last-child {
margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
font-size: 12px;
font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
margin: 0 0px;
padding: 0px 0px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px;
}

pre>code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent;
}

pre {
background-color: #f8f8f8;
border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px;
}

pre code, pre tt {
background-color: transparent;
border: none;
}

kbd {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #DDDDDD;
background-image: linear-gradient(#F1F1F1, #DDDDDD);
background-repeat: repeat-x;
border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
border-image: none;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: 1px;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
line-height: 10px;
padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
border-left: 4px solid #DDD;
padding: 0 15px;
color: #777;
}

blockquote>:first-child {
margin-top: 0px;
}

blockquote>:last-child {
margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
clear: both;
margin: 15px 0;
height: 0px;
overflow: hidden;
border: none;
background: transparent;
border-bottom: 4px solid #ddd;
padding: 0;
}

/* TABLES
=============================================================================*/

table th {
font-weight: bold;
}

table th, table td {
border: 1px solid #ccc;
padding: 6px 13px;
}

table tr {
border-top: 1px solid #ccc;
background-color: #fff;
}

table tr:nth-child(2n) {
background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
max-width: 100%
}
-->

pytho自动化开发 day09

Date:2016.03.12

    @南非波波

课程大纲:

day08

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

day09

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

推荐电影

<权利的游戏:冰与火之歌>  <纸牌屋> <绝命毒师>
《林大看美国》

一、回顾进程、线程

python调用C的原生线程
GIL(全局解释器)防止数据被修改异常。使用线程锁控制同时仅有一个线程对数据有操作权限
全局解释器限制的是原生C线程,
python同一时刻只有一个线程
python会处理不同cpu核之间的进程切换
父进程与子进程之间默认不能共享数据

获取线程的数据

#!/usr/local/env python3
'''
Author:@南非波波
Blog:http://www.cnblogs.com/songqingbo/
E-mail:qingbo.song@gmail.com
'''
import time,threading data = [] #列表是一个安全的内存空间,可以不用加线程锁
def run(n):
'''
定义一个run方法,返回的n的n次方
:param n:
:return:
'''
data.append(n**n)
return n**n
#创建一个多线程
t = threading.Thread(target=run,args=[8,])
t.start()
t.join() #起阻塞作用,让主进程等待线程执行完再执行主进程 默认无限期的等待,添加一个超时时间timeout=3.在守护线程下面是不好使的
print(data)

二、 队列

  1. 先进先出

    python队列queue默认的是先进先出。
    import queue
    Queue = queue.Queue(maxsize=5)
    Queue.put((2,["swht","shen"]))
    Queue.put((5,{"name":"swht"}))
    Queue.put((1,"sdsd"),timeout=2)
    for i in range(Queue._qsize()):
    print("data%s:%s" % (i,Queue.get()))
    返回结果:
    data0:(2, ['swht', 'shen'])
    data1:(5, {'name': 'swht'})
    data2:(1, 'sdsd')
  2. 后进先出

    python队列支持后面进去的消息最先被取出。
    python队列queue默认的是先进先出。
    import queue
    Queue = queue.LifoQueue(maxsize=5)
    Queue.put((2,["swht","shen"]))
    Queue.put((5,{"name":"swht"}))
    Queue.put((1,"sdsd"),timeout=2)
    for i in range(Queue._qsize()):
    print("data%s:%s" % (i,Queue.get()))
    返回结果:
    data0:(1, 'sdsd')
    data1:(5, {'name': 'swht'})
    data2:(2, ['swht', 'shen'])
  3. 按照优先级

    python queue支持设置优先级,取消息可以安装优先级顺序取出消息
    import queue
    Queue = queue.PriorityQueue(maxsize=5)
    Queue.put((2,["swht","shen"]))
    Queue.put((5,{"name":"swht"}))
    Queue.put((1,"sdsd"),timeout=2)
    for i in range(Queue._qsize()):
    print("data%s:%s" % (i,Queue.get()))
    返回结果:
    data0:(1, 'sdsd')
    data1:(2, ['swht', 'shen'])
    data2:(5, {'name': 'swht'})

生产者-消费者模型:

  1. 一对一:

    import threading,queue,time
    def consumer(n):
    '''
    消费者,消费生产者产生的消息、数据
    :param n: 消费者标志
    :return:
    '''
    while True:
    print("\033[32;1m消费者[%s]\033[0m 获取消息 %s" % (n,q.get()))
    time.sleep(1)
    q.task_done() #消费者等待生产者生产消息 def prodeucer(n):
    '''
    生产者,生产消息、数据
    :param n: 生产者标志
    :return:
    '''
    count = 1
    while True:
    print("\033[31;1m生产者[%s]\033[0m 生产消息 %s" % (n,count))
    q.put(count)
    count += 1
    q.join() #生产者阻塞
    print("==================") #发出信号:消息已经生产 q = queue.Queue()
    c1 = threading.Thread(target=consumer,args=[1,]) p1 = threading.Thread(target=prodeucer,args=["swht",]) c1.start()
    p1.start() 结果: 生产者[swht] 生产消息 1
    消费者[1] 获取消息 1
    ==================
    生产者[swht] 生产消息 2
    消费者[1] 获取消息 2
    ==================
    生产者[swht] 生产消息 3
    消费者[1] 获取消息 3
    ==================
    生产者[swht] 生产消息 4
    消费者[1] 获取消息 4
    ==================
    生产者[swht] 生产消息 5
    消费者[1] 获取消息 5
    ==================
    生产者[swht] 生产消息 6
    消费者[1] 获取消息 6
    ==================
    生产者[swht] 生产消息 7
    消费者[1] 获取消息 7
    ==================
  2. 一对多:

    import threading,queue,time
    def consumer(n):
    '''
    消费者,消费生产者产生的消息、数据
    :param n: 消费者标志
    :return:
    '''
    while True:
    print("\033[32;1m消费者[%s]\033[0m 获取消息 %s" % (n,q.get()))
    time.sleep(1)
    q.task_done() #消费者等待生产者生产消息 def prodeucer(n):
    '''
    生产者,生产消息、数据
    :param n: 生产者标志
    :return:
    '''
    count = 1
    while True:
    print("\033[31;1m生产者[%s]\033[0m 生产消息 %s" % (n,count))
    q.put(count)
    count += 1
    q.join() #生产者阻塞
    print("==================") #发出信号:消息已经生产 q = queue.Queue()
    c1 = threading.Thread(target=consumer,args=[1,])
    c2 = threading.Thread(target=consumer,args=[2,])
    c3 = threading.Thread(target=consumer,args=[3,])
    p1 = threading.Thread(target=prodeucer,args=["swht",]) c1.start()
    c2.start()
    c3.start()
    p1.start() 结果: 生产者[swht] 生产消息 1
    消费者[1] 获取消息 1
    ==================
    生产者[swht] 生产消息 2
    消费者[2] 获取消息 2
    ==================
    生产者[swht] 生产消息 3
    消费者[3] 获取消息 3
    ==================
    生产者[swht] 生产消息 4
    消费者[1] 获取消息 4
    ==================
    生产者[swht] 生产消息 5
    消费者[2] 获取消息 5
    ==================
    生产者[swht] 生产消息 6
    消费者[3] 获取消息 6
    ==================
    生产者[swht] 生产消息 7
    消费者[1] 获取消息 7
    ==================
  3. 多对多:

    import threading,queue,time
    def consumer(n):
    '''
    消费者,消费生产者产生的消息、数据
    :param n: 消费者标志
    :return:
    '''
    while True:
    print("\033[32;1m消费者[%s]\033[0m 获取消息 %s" % (n,q.get()))
    time.sleep(1)
    q.task_done() #消费者等待生产者生产消息 def prodeucer(n):
    '''
    生产者,生产消息、数据
    :param n: 生产者标志
    :return:
    '''
    count = 1
    while True:
    print("\033[31;1m生产者[%s]\033[0m 生产消息 %s" % (n,count))
    q.put(count)
    count += 1
    q.join() #生产者阻塞
    print("==================") #发出信号:消息已经生产 q = queue.Queue()
    c1 = threading.Thread(target=consumer,args=[1,])
    c2 = threading.Thread(target=consumer,args=[2,])
    c3 = threading.Thread(target=consumer,args=[3,])
    p1 = threading.Thread(target=prodeucer,args=["swht",])
    p2 = threading.Thread(target=prodeucer,args=["shen",])
    p3 = threading.Thread(target=prodeucer,args=["alex",]) c1.start()
    c2.start()
    c3.start()
    p1.start()
    p2.start()
    p3.start() 结果: 生产者[swht] 生产消息 1
    生产者[shen] 生产消息 1
    消费者[1] 获取消息 1
    生产者[alex] 生产消息 1
    消费者[2] 获取消息 1
    消费者[3] 获取消息 1
    ==================
    生产者[swht] 生产消息 2
    消费者[1] 获取消息 2
    ==================
    生产者[swht] 生产消息 3
    消费者[2] 获取消息 3
    ==================
    生产者[swht] 生产消息 4
    消费者[3] 获取消息 4
    ==================
    生产者[alex] 生产消息 2
    消费者[1] 获取消息 2
    ==================
    生产者[swht] 生产消息 5
    ==================
    生产者[shen] 生产消息 2
    消费者[2] 获取消息 2
    消费者[3] 获取消息 5
    ==================
    生产者[swht] 生产消息 6
    ==================
    生产者[shen] 生产消息 3
    消费者[1] 获取消息 3
    消费者[3] 获取消息 6
    ==================
    生产者[shen] 生产消息 4
    消费者[2] 获取消息 4
    ==================
    生产者[shen] 生产消息 5
    消费者[1] 获取消息 5
    ==================
    生产者[shen] 生产消息 6
    消费者[3] 获取消息 6
    ==================
    生产者[shen] 生产消息 7
    消费者[2] 获取消息 7
    ==================

三、协程

协程是一种用户态的轻量级线程。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

通过协程进行线程内切换,虽然还是串行的执行,但是因为切换速度快,可以达到一种并发的效果。用户自行控制

协程的好处:

无需线程上下文切换的开销
无需原子操作锁定及同步的开销
方便切换控制流,简化编程模型
高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。

缺点:

无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。
进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序

通过yeild简单模拟协程

import time
import queue
def consumer(name):
print("--->starting eating baozi...")
while True:
new_baozi = yield
print("[%s] is eating baozi %s" % (name,new_baozi))
#time.sleep(1) def producer(): r = con.__next__()
r = con2.__next__()
n = 0
while n < 5:
n +=1
con.send(n)
con2.send(n)
print("\033[32;1m[producer]\033[0m is making baozi %s" %n ) if __name__ == '__main__':
con = consumer("c1")
con2 = consumer("c2")
p = producer() '''
结果:
--->starting eating baozi...
--->starting eating baozi...
[c1] is eating baozi 1
[c2] is eating baozi 1
[producer] is making baozi 1
[c1] is eating baozi 2
[c2] is eating baozi 2
[producer] is making baozi 2
[c1] is eating baozi 3
[c2] is eating baozi 3
[producer] is making baozi 3
[c1] is eating baozi 4
[c2] is eating baozi 4
[producer] is making baozi 4
[c1] is eating baozi 5
[c2] is eating baozi 5
[producer] is making baozi 5
'''

greenlet模块

greenlet模块可以简单的实现协程之间的切换

示例代码:

from greenlet import greenlet
def test1():
print(12)
gr2.switch()
print(34)
gr2.switch()
def test2():
print(56)
gr1.switch()
print(78) gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

gevent模块

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

gevent模块实现协程在遇到IO阻塞时进行切换的功能。避免了协程的致命缺点:一个协程阻塞,整个线程宕掉

示例代码:

#!/usr/local/env python3
'''
Author:@南非波波
Blog:http://www.cnblogs.com/songqingbo/
E-mail:qingbo.song@gmail.com
'''
import gevent def foo():
print('\033[32;1mRunning in foo\033[0m')
gevent.sleep(1)
print('\033[32;1mExplicit context switch to foo again\033[0m') def bar():
print('Explicit context to bar')
gevent.sleep(1)
print('Implicit context switch back to bar') def exe():
print('\033[31;1mExplicit context to bar\033[0m')
gevent.sleep(1)
print('\033[31;1mImplicit context switch back to bar\033[0m') gevent.joinall([
gevent.spawn(foo),
gevent.spawn(bar),
gevent.spawn(exe),
])

附注:

gevent模块安装:
1. windows环境: 使用pip进行安装:pip2 install gevent
pip3 install gevent 2. Linux环境: 使用pip进行安装:pip2 install gevent
pip3 install gevent
使用源码包编译安装:

四、select、poll、epoll多路IO阻塞

  1. select

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

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

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

  2. poll

    poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。

    select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发(Level Triggered)。

  3. epoll

    epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂。

    epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。

    另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epollctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epollwait()时便得到通知。

select示例:

server端

#!/usr/local/env python3
'''
Author:@南非波波
Blog:http://www.cnblogs.com/songqingbo/
E-mail:qingbo.song@gmail.com
'''
'''
通过echo server例子了解select 是如何通过单进程实现同时处理多个非阻塞的socket连接
''' import select
import socket
import sys
import queue # 创建一个TCP/IP socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(False) #设置非阻塞 ==>server.setblocking(0) # 绑定端口和ip地址
server_address = ('localhost', 10000)
print(sys.stderr, 'starting up on %s port %s' % server_address) #
# print >> sys.stderr,'starting up on %s port %s' % server_address
server.bind(server_address) # 监听连接,允许同时有5个链接
server.listen(5)
#select()方法接收并监控3个通信列表
#1.所有的输入数据,即外部发过来的数据;
#2.监控和监听所要发出去的数据;
#3.监控错误信息
# 创建输入列表将输入的信息传递给select()
inputs = [ server ] # 创建输出列表将输出的信息传递给select()
outputs = [ ] #创建一个缓存队列,用来存储每个连接的输入或输出的数据,然后由select去出来再发出去。
message_queues = {}
#程序的主循环,当调用select()时会阻塞和等待直到新的连接和数据进来
while inputs: # Wait for at least one of the sockets to be ready for processing
print( '\nwaiting for the next event')
#readable 代表socket连接有数据可以接收(resv)
#writable 代表socket连接有可以进行发送(send)的数据
#exceptional 存放连接通信出现的error错误信息。这里使用inputs信息代替
readable, writable, exceptional = select.select(inputs, outputs, inputs)
# Handle inputs
#readsble list中可以有3种可能状态,第一种是如果这个socket是main"server" socket,它负责监听客户端的连接,
for s in readable:
# 如果这个main server socket出现在readable里,那代表这是server端已经ready来接收一个新的连接进来了
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept() #接收一个新的连接
print('new connection from', client_address) #打印客户端连接的地址
connection.setblocking(False) #设置成非阻塞状态
inputs.append(connection) #将链接添加到inputs链表中 # Give the connection a queue for data we want to send
message_queues[connection] = queue.Queue()
#这种情况是这个socket是已经建立了的连接,它把数据发了过来,这个时候就可以通过recv()来接收它发过来的数据,
# 然后把接收到的数据放到queue里,这样就可以把接收到的数据再传回给客户端了。
else:
data = s.recv(1024) #接收客户端传递的数据
if data: #如果接收的数据不为空
# A readable client socket has data
print(sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) )
message_queues[s].put(data) #从缓存队列里获取数据然后将其传递给客户端
# 如果连接不在发送列表中,则将其添加到发送列表中
if s not in outputs:
outputs.append(s)
else: #如果接收的数据为空
# Interpret empty result as closed connection
print('closing', client_address, 'after reading no data')
# Stop listening for input on the connection
#停止监听这个连接
# 这种情况就是这个客户端已经断开了,所以你再通过recv()接收到的数据就为空了,
# 所以这个时候你就可以把这个跟客户端的连接关闭了。
if s in outputs:
outputs.remove(s) #既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉
inputs.remove(s) #inputs中也删除掉
s.close() #把这个连接关闭掉 # Remove message queue
del message_queues[s]
# 对于writable list中的socket,也有几种状态,如果这个客户端连接在跟它对应的queue里有数据,就把这个数据取出来再发回给这个客户端,否则就把这个连接从output list中移除,
# 这样下一次循环select()调用时检测到outputs list中没有这个连接,那就会认为这个连接还处于非活动状态
for s in writable:
try:
next_msg = message_queues[s].get_nowait() #获取信息不阻塞等待
except queue.Empty:
# No messages waiting so stop checking for writability.
print('output queue for', s.getpeername(), 'is empty')
outputs.remove(s) #队列为空,则从发送列表中删除连接
else:
print( 'sending "%s" to %s' % (next_msg, s.getpeername()))
s.send(next_msg) #当从队列中获取到信息时将其发送给客户端
#果在跟某个socket连接通信过程中出了错误,就把这个连接对象在inputs\outputs\message_queue中都删除,
# 再把连接关闭掉
for s in exceptional:
print('handling exceptional condition for', s.getpeername() )
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close() # Remove message queue
del message_queues[s] client端
#!/usr/local/env python3
'''
Author:@南非波波
Blog:http://www.cnblogs.com/songqingbo/
E-mail:qingbo.song@gmail.com
'''
import socket
import sys messages = [ 'This is the message. ',
'It will be sent ',
'in parts.',
]
server_address = ('localhost', 10000) # Create a TCP/IP socket
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM),
socket.socket(socket.AF_INET, socket.SOCK_STREAM),
] # Connect the socket to the port where the server is listening
print(sys.stderr, 'connecting to %s port %s' % server_address)
for s in socks:
s.connect(server_address) for message in messages: # Send messages on both sockets
for s in socks:
print(sys.stderr, '%s: sending "%s"' % (s.getsockname(), message))
s.send(bytes(message,'utf8')) # Read responses on both sockets
for s in socks:
data = s.recv(1024)
print(sys.stderr, '%s: received "%s"' % (s.getsockname(), data))
if not data:
print(sys.stderr, 'closing socket', s.getsockname())
s.close()

五、堡垒机模块

参考:http://www.cnblogs.com/wupeiqi/articles/5095821.html

  1. 模块安装:

    pip2 install paramiko

    pip3 install paramiko
    #win下python3安装paramiko模块涉及到编译工具的问题没有安装成功,在Linux环境下面测试下面的代码正常。

  2. 示例代码

    #!/usr/local/env python3
    '''
    Author:@南非波波
    Blog:http://www.cnblogs.com/songqingbo/
    E-mail:qingbo.song@gmail.com
    '''
    import paramiko
    '''
    基于用户名密码连接
    '''
    # 创建SSH对象
    ssh = paramiko.SSHClient()
    # 允许连接不在know_hosts文件中的主机
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    # 连接服务器
    ssh.connect(hostname='192.168.137.5', port=22, username='root', password='shen1234') # 执行命令
    stdin, stdout, stderr = ssh.exec_command('df -h')
    # 获取命令结果
    result = stdout.read()
    #打印结果
    print(result.decode())
    # 关闭连接
    ssh.close() import paramiko transport = paramiko.Transport(('192.168.137.5', 22))
    transport.connect(username='root', password='shen1234') ssh = paramiko.SSHClient()
    ssh._transport = transport stdin, stdout, stderr = ssh.exec_command('ifconfig')
    print(stdout.read().decode()) transport.close() import paramiko def ssh_connet(host,user,shell):
    '''
    实现ssh远程登录服务器进行相关操作
    :param host: 远程服务器地址和端口号 host_ip:port
    :param user: 远程服务器用户名密码 user:passwd
    :parm shell: 需要执行的shell命令
    :return: 返回用户执行shell命令的
    '''
    host = host.split(":")
    user = user.split(":")
    transport = paramiko.Transport((host[0], int(host[1])))
    transport.connect(username=user[0], password=user[1])
    ssh = paramiko.SSHClient()
    ssh._transport = transport
    stdin, stdout, stderr = ssh.exec_command(shell)
    reaults = stdout.read().decode()
    transport.close()
    return reaults
    print(ssh_connet("192.168.137.5:22","root:shen1234","df -h"))

基于公钥密钥连接: import paramiko

def ssh_connet(host,user,private_key,shell):
'''
实现ssh远程登录服务器进行相关操作
:param host: 远程服务器地址和端口号 host_ip:port
:param user: 远程服务器用户名密码 user:passwd
:param private_key: 基于公钥的形式登录
:parm shell: 需要执行的shell命令
:return: 返回用户执行shell命令的
'''
host = host.split(":")
transport = paramiko.Transport((host[0], int(host[1])))
transport.connect(username=user[0], key=private_key)
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command(shell)
reaults = stdout.read().decode()
transport.close()
return reaults
private_key = paramiko.RSAKey.from_private_key_file('/home/auto/.ssh/id_rsa')
print(ssh_connet("192.168.137.5:22","root",private_key,"df -h"))

六、mysql操作模块

rollback()事务回滚 excutemany()

作业:

1.  select()代码,注释
2. 主机批量管理工具
1. saltstack文档阅读(常用架构弄清楚)
2. 修改主机批量管理工具的架构

python开发学习-day09(队列、多路IO阻塞、堡垒机模块、mysql操作模块)的更多相关文章

  1. Python之路,Day12 - 那就做个堡垒机吧

    Python之路,Day12 - 那就做个堡垒机吧   本节内容 项目实战:运维堡垒机开发 前景介绍 到目前为止,很多公司对堡垒机依然不太感冒,其实是没有充分认识到堡垒机在IT管理中的重要作用的,很多 ...

  2. python开发学习-day10(select/poll/epoll回顾、redis、rabbitmq-pika)

    s12-20160319-day10 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  3. Python 开发学习路线

    第一阶段:Python 语言基础 数据类型 流程控制 常用模块 函数.迭代器.装饰器 递归.迭代.反射 面向对象编程 购物车程序 计算器程序开发 模拟人生游戏开发 第二阶段:网络编程 Socket c ...

  4. python开发学习-day01 (python安装与版本、字符串、字典、运算符、文件)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  5. python开发学习-day02(元组、字符串、列表、字典深入)

    s12-20160109-day02 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  6. python开发学习-day06(模块拾忆、面向对象)

    s12-20160130-day06 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: ...

  7. python开发_tkinter_菜单选项中英文切换_菜单选项不可用操作_博主推荐

    我使用的python版本为:3.3.2 如果你对python中tkinter模块的菜单操作不是很了解,你可以看看: python开发_tkinter_窗口控件_自己制作的Python IDEL_博主推 ...

  8. Python之路【第九篇】堡垒机基础&数据库操作

    复习paramiko模块 Python的paramiko模块,是基于SSH用于连接远程服务器并执行相关操作. SSHClient #!/usr/bin/env python #-*- coding:u ...

  9. python之实现批量远程执行命令(堡垒机)

    python远程批量执行 我并不是一个专业的开发,我一直在学习linux运维,对于python也是接触不久,所以代码写的并不是很规范简洁. 前段时间一个同学找我一起做一个自动化运维平台,我对pytho ...

随机推荐

  1. jsonP 后台写法 及 层级树型数据递归查询

    Controller层: package com.taotao.rest.controller; import org.springframework.beans.factory.annotation ...

  2. FreeRTOSv9.0.0在STM32F103RCT6上的移植

    1.去官网下载源代码(FreeRTOSv9.0.0.exe) 2.取出Source文件夹,根据单片机和编译器不同,删除不需要的文件,如下图 3.在CORTEX_STM32F103_IAR文件夹中取出P ...

  3. fmt:formatNumber use locale display negative currency in -$xxx.xx format in JSTL

    First, we want to know our own locale,how to display the locale in a JSTL? <c:out value="${p ...

  4. codeforces Good bye 2016 E 线段树维护dp区间合并

    codeforces Good bye 2016 E 线段树维护dp区间合并 题目大意:给你一个字符串,范围为‘0’~'9',定义一个ugly的串,即串中的子串不能有2016,但是一定要有2017,问 ...

  5. cin.getline()与getline()

    C++中有两个getline函数, cin.getline()与getline()  这两个函数相似,但是 这两个函数分别定义在不同的头文件中.   cin.getline()属于istream流,而 ...

  6. CSS属性的私有前缀

    在CSS属性能中,我们常常能看到-webkit-,-moz-之类的前缀,这种就叫做浏览器私有前缀,是浏览器对于新CSS属性的一个提前支持.-webkit-是webkit内核的,-moz-是Firefo ...

  7. MappedByteBuffer以及ByteBufer的底层原理

    最近在用java中的ByteBuffer,一直不明所以,尤其是对MappedByteBuffer使用的内存映射这个概念云里雾里. 于是首先补了物理内存.虚拟内存.页面文件.交换区的只是:小科普——物理 ...

  8. LintCode 394: First Will Win

    LintCode 394: First Will Win 题目描述 有n个硬币排成一条线.两个参赛者轮流从右边依次拿走1或2个硬币,直到没有硬币为止.拿到最后一枚硬币的人获胜. 请判定 第一个玩家 是 ...

  9. 微信小程序开发(四)线程架构和开发步骤

    线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...

  10. react系列一,react虚拟dom如何转成真实的dom

    react,想必作为前端开发一定不陌生,组件化以及虚拟dom使得react成为最受欢迎额前端框架之一.我们知道react是基于虚拟dom的,但是什么是虚拟dom呢,其实就是一组js对象,那么我们今天就 ...