Prthon多线程和模块

  1. 案例1:简化除法判断
  2. 案例2:分析apache访问日志
  3. 案例3:扫描存活主机
  4. 案例4:利用多线程实现ssh并发访问

1 案例1:简化除法判断

1.1 问题

编写mydiv.py脚本,主要要求如下:

  • 提示用户输入一个数字作为除数
  • 如果用户按下Ctrl+C或Ctrl+D则退出程序
  • 如果用户输入非数字字符,提示用户应该输入数字
  • 如果用户输入0,提示用户0不能作为除数

1.2 方案

使用if语句判断除数是否合适,需要编写多条语句。有了异常处理,可以本着先做,错了再说的逻辑。直接把除法操作放在try语句中执行,根据产生的异常做相应的处理。

另外,Ctrl+C或Ctrl+D只能通过异常捕获。

异常捕获的语法如下:

  1. try:
  2. A
  3. except:
  4. B
  5. else:
  6. C
  7. finally:
  8. D

把可能发生异常的语句放在A里面执行,如果出现异常则执行B语句,没有异常则执行C语句。不管是否出现异常都会执行D语句。

捕获异常时,可以使用多个except语句,每个except语句捕获一个异常,每个异常给定不同的处理方法。也可以把多个异常放在同一个except语句后面,但是务必注意,多个异常写在相同的一行,一定要注括号括起来,放在元组中。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写脚本

  1. #!/usr/bin/env python
  2. import  sys
  3. while True:
  4. try:
  5. result = 100 / int(raw_input('enter a number: '))
  6. except (ValueError, ZeroDivisionError), e:   #将异常原因保存在变量e中
  7. print "invalid input:", e
  8. continue
  9. except  (EOFError, KeyboardInterrupt):
  10. sys.exit(1)
  11. break
  12. print  result

步骤二:测试脚本执行

  1. [root@py01 bin]# ./mydiv.py
  2. enter a number: 0
  3. invalid input: integer division or modulo by zero
  4. enter a number: abc
  5. invalid input: invalid literal for int() with base 10: 'abc'
  6. enter a number: 3
  7. 33

案例2:分析apache访问日志

2.1 问题

编写用于分析apache日志的脚本,主要要求如下:

  • 统计每个客户端访问apache服务器的次数
  • 将统计信息通过字典的方式显示出来
  • 分别统计客户端是Firefox和MSIE的访问次数
  • 分别使用函数式编程和面向对象编程的方式实现

2.2 方案

涉及到文本处理时,正则表达式将是一个非常强大的工具。匹配客户端的IP地址,可以使用正则表达式的元字符,匹配字符串可以直接使用字符的表面含义。

入门级程序员的写法,使用顺序的结构,直接编写。这种方法虽然可以得出结果,但是代码难以重用。参考步骤一。

进阶的写法可以采用函数式编程,方便日后再次使用。参考步骤二。

最后,还可以使用OOP的编程方法,先定义一个统计类,该类将正则表达式作为它的数据属性。再定义一个方法,从指定的文件中搜索正则表达式出现的次数,并将其存入到一个字典中。参考步骤三。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:简单实现

  1. [root@py01 bin]# vim countweb.py
  2. #!/usr/bin/env python
  3. import re
  4. logfile = '/var/log/httpd/access_log'
  5. cDict = {}
  6. patt_ip = '^\d+\.\d+\.\d+\.\d+'         #定义匹配IP地址的正则表达式
  7. with open(logfile) as f:
  8. for eachLine in f:
  9. m = re.search(patt_ip, eachLine)
  10. if m is not None:
  11. ipaddr = m.group()
  12. #如果IP地址已在字典中,将其值加1,否则初始值设置为1
  13. cDict[ipaddr] = cDict.get(ipaddr, 0) + 1
  14. print cDict

步骤二:使用函数式编程实现

  1. [root@py01 bin]# vim countweb2.py
  2. !/usr/bin/env python
  3. import re
  4. def countPatt(patt, fname):   #定义可以在指定文件中搜索指定字符串的函数
  5. cDict = {}
  6. with open(fname) as f:
  7. for eachLine in f:
  8. m = re.search(patt, eachLine)
  9. if m is not None:
  10. k = m.group()
  11. cDict[k] = cDict.get(k, 0) + 1
  12. return cDict
  13. def test():
  14. logfile = '/var/log/httpd/access_log'
  15. patt_ip = '^\d+\.\d+\.\d+\.\d+'
  16. print countPatt(patt_ip, logfile)
  17. patt_br = 'Firefox|MSIE'
  18. print countPatt(patt_br, logfile)
  19. if __name__ == '__main__':
  20. test()

案例3:扫描存活主机

3.1 问题

编写扫描存活主机的脚本,主要要求如下:

  • 调用系统的ping命令进行扫描
  • 扫描教室环境下所有存活的主机
  • 采用多线程的方式编写
  • 方案

os模块的system()函数可以调用系统命令,其返回值是系统命令退出码,也就是如果系统命令成功执行,返回0,如果没有成功执行,返回非零值。

本例扫描主机,可以调用系统的ping命令,通过退出码来判断是否ping通了该主机。如果顺序执行,每个ping操作需要消耗数秒钟,全部的254个地址需要10分钟以上。而采用多线程,可以实现对这254个地址同时执行ping操作,并发的结果就是将执行时间缩短到了10秒钟左右。

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写脚本

  1. [root@py01 bin]# vim mtping.py
  2. #!/usr/bin/env python
  3. import subprocess
  4. import threading
  5. import sys
  6. def ping(ip):
  7. result = subprocess.call("ping -c2 %s &> /dev/null" % ip, shell=True)
  8. if result:
  9. print "%s:down" % ip
  10. else:
  11. print "%s:up" % ip
  12. if __name__ == '__main__':
  13. if len(sys.argv) != 2:
  14. print "Usage: %s subnet" % sys.argv[0]
  15. sys.exit(1)
  16. net_list = sys.argv[1].split('.')
  17. net = '.'.join(net_list[:-1])
  18. ips = ("%s.%s" % (net, i) for i in range(1, 255))
  19. for ip in ips:
  20. t = threading.Thread(target=ping, args=(ip,))
  21. t.start()

步骤二:测试脚本执行

  1. [root@py01 bin]# python mtping.py 172.40.51.0

脚本接受命令行参数,只要给定网段就可以实现对该网段中所有ip地址的ping操作。


案例4:利用多线程实现ssh并发访问

4.1 问题

编写ssh客户端脚本,主要要求如下:

  • 在文件中取出所有远程主机IP地址
  • 在shell命令行中接受远程服务器IP地址文件、远程服务器密码以及在远程主机上执行的命令
  • 通过多线程实现在所有的远程服务器上并发执行命令
  • 方案

python的paramiko模块可以实现ssh客户端的功能,使用起来也比较简单。但是当服务器非常多的时候,每台服务器上执行完全相同的简单操作,也会花费大量的时间。

通过ssh加上多线程,可以实现并发访问。为了将程序写的灵活性更强,把要执行的命令以位置参数的方式来提供。

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:编写脚本

  1. [root@py01 bin]# vim remote_comm.py
  2. #!/usr/bin/env python
  3. import paramiko
  4. import os
  5. import sys
  6. import threading
  7. def remote_comm(host, password, comm):
  8. ssh = paramiko.SSHClient()
  9. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  10. ssh.connect(host, username='root', password=password)
  11. stdin, stdout, stderr = ssh.exec_command(comm)
  12. out = stdout.read()
  13. err = stderr.read()
  14. if out:
  15. print "[%s:out]: %s" % (host, out),
  16. if err:
  17. print "%s:Error: %s", (host, err),
  18. ssh.close()
  19. if __name__ == '__main__':
  20. if len(sys.argv) != 4:
  21. print "Usage: %s ipfile password 'comm'" % sys.argv[0]
  22. sys.exit(1)
  23. ipfile = sys.argv[1]
  24. if not os.path.isfile(ipfile):
  25. print "No such file: %s" % ipfile
  26. sys.exit(2)
  27. password = sys.argv[2]
  28. comm = sys.argv[3]
  29. with open(ipfile) as fobj:
  30. for line in fobj:
  31. ip = line.strip()
  32. t = threading.Thread(target=remote_comm, args=(ip, password, comm))
  33. t.start()

步骤二:测试脚本执行

  1. [root@py01 bin]# python remote_comm.py ipaddr.txt tedu.cn 'useradd bob'

脚本接受命令行参数,其中ipaddr.txt是存放所有远程主机ip地址的文件,文件中每个ip地址占一行。tedu.cn是远程主机的密码(所有远程主机密码需要是一致的)。最后的命令需要写在引号中。

该示例执行成功后,会在所有远程主机上创建一个名为bob的用户。

Prthon多线程和模块的更多相关文章

  1. Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例

    由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二 ...

  2. 网络编程 多线程/socketserver模块/ threading.local

    线程:进程中负责程序执行的执行单元. 多线程:在1个进程中存在多个线程. 进程只是用来把资源集中在一起,而线程才是cpu上的执行单位. 每个进程都会默认有一个控制线程也叫作主线程. 进程之间是竞争关系 ...

  3. 再看python多线程------threading模块

    现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个“,”否则会抛参数异常的错误. 如下: for i ...

  4. day 30 多线程 socketserver模块补充

    内容回顾: socket 模块 服务端:收发数据 - > accept/recv 客户端:收发数据 -> connect/recv 1. 考试题 1. 解释性和编译型 编译型: 先把代码编 ...

  5. 多线程threading模块

    python的多线程编程 简介 多线程编程技术可以实现代码并行性,优化处理能力,同时功能的更小划分可以使代码的可重用性更好.Python中threading和Queue模块可以用来实现多线程编程. 详 ...

  6. Python:多线程threading模块

    目录 Thread对象 Lock对象 local对象 Thread对象: 多任务可以由多进程完成,也可以由一个进程内的多线程完成.进程是由至少1个线程组成的. threading模块在较低级的模块 _ ...

  7. python编程中的并发------多线程threading模块

    任务例子:喝水.吃饭动作需要耗时1S 单任务:(耗时20s) for i in range(10): print('a正在喝水') time.sleep(1) print('a正在吃饭') time. ...

  8. Python_多线程threading模块

    python 在执行的时候会淡定的在CPU上只允许一个线程运行,故Python在多核CPU的情况下也只能发挥出单核的功能,其中的原因:gil锁 gil 锁 (全局解释器锁):每个线程在执行时都需要先获 ...

  9. Python(多线程threading模块)

    day27 参考:http://www.cnblogs.com/yuanchenqi/articles/5733873.html CPU像一本书,你不阅读的时候,你室友马上阅读,你准备阅读的时候,你室 ...

随机推荐

  1. 【工具】---- webpack简析

    1. 什么是webpack 一个现代 JavaScript 应用程序的静态模块打包器(module bundler),它会分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行 ...

  2. Azure CLI 简单入门

    Azure CLI 是什么 Azure 命令行接口 (CLI) 是用于管理 Azure 资源的 Microsoft 跨平台命令行体验. Azure CLI 易于学习,是构建适用于 Azure 资源的自 ...

  3. 【.net core】电商平台升级之微服务架构应用实战

    一.前言 这篇文章本来是继续分享IdentityServer4 的相关文章,由于之前有博友问我关于微服务相关的问题,我就先跳过IdentityServer4的分享,进行微服务相关的技术学习和分享.微服 ...

  4. 「CSS」常见的清除浮动方法

    下面介绍几种清除浮动的方案,供大家参考: 使用额外的标签clear:both .parent {padding: 10px;width: 200px;background: red;} .child ...

  5. 一口气说出 6种,@Transactional注解的失效场景

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 一口气说出 9种 分布式ID生成方式,面试官有点懵了 面试总被问 ...

  6. Linux命令进阶篇-文件查看与查找

    上一篇的博客对于Linux如何在不同目录下跳转和查看目录下内容做出了总结,主要靠cd和ls,很常见也很实用.但是你看到目录下面那么多不同花花绿绿的文件,心里是不是痒痒,是不是想进去一探究竟,有办法! ...

  7. VLAN间的通信

    多臂路由/单臂路由 :实现不同VLAN间的通信 1.多臂路由 划分两个vlan,将主机划分到不同vlan中 配置ip地址,(注意:不同vlan在不同的网络下) 将交换机的两个端口分别与路由器连接,将这 ...

  8. django之forms组件,cookie&session

    forms组件 先自己实现注册功能,并且对用户输入的信息加限制条件如果用户输入的信息不符合条件,前端展示报错信息 from django.shortcuts import render,HttpRes ...

  9. Servlet(三)----Servlet体系与HTTP

    ## Servlet的体系结构 Servlet  ---  接口 | | GenericServlet  ---  抽象类 | | HttpServlet  --  抽象类 GenericServle ...

  10. Falling Squares

    2020-01-08 10:16:37 一.Falling squares 问题描述: 问题求解: 本题其实也是一条经典的区间问题,对于区间问题,往往可以使用map来进行区间的维护操作. class ...