multithread如何写

这是我第一次写multithread,所以就是照着例子学,下面是我用来学的例子

来自于”Automate the boring stuff with Python”的15.6

import threading, time

print "Start of the program"

def takeANap():
time.sleep(5)
print "Wake up!" thread1 = threading.Thread(target = takeANap)
thread1.start() print "End of the program"

OK, 这个小程序的结果会是End of… 这一句先print出来,然后Wake up再出现,其实”Automate the boring….”这本书里对多线程就讲了两个例子,这是第一个,第二个是讲了如何向多线程传递参数,但是看完之后发现对今天的程序帮助不大,因为今天的程序有很大的一部分困难就是print造成的,那么下面就说说源程序的需求和第一次失败的尝试。

以一个多线程print的程序为例子

  • 需求:
    使用多线程,在三台不同的路由器上,show arp并输出

  • 问题:
    很明显,输出会messed up, 因为线程各自有快有慢

  • 初步想到的方法

  • 可以把两个的结果存到外部文件,然后有条理的读取,然后有条理的print。我认为这样是可行的,但是这样显然练习不到multithread的特征,因为multithread是关乎内存的,存到磁盘再读,感觉上有些违背了充分利用多线程的优势,况且这是一个小程序,就是纯粹显示的问题。

  • threading.Lock()

先说,这个失败了,因为print比较特殊,它自己的打印快慢依然会影响,这不是一个线程是否被执行完的问题,而是一个线程执行完了之后,它的输出打印并不够快而如何解决的问题,所以Lock()帮不上忙

Lock()的相关代码:

我依照这个链接里的例子创建了自己的thread的子类

  • 这个myThread会以device类,也就是某个路由器为对象,调取printARP

  • 我在print的前后分别加了acquire()用于上锁和release()用于解锁

class myThread(threading.Thread):
def __init__(self, device):
threading.Thread.__init__(self)
self.device = device
def run(self):
threadLock1 = threading.Lock()
threadLock1.acquire()
printARP(self.device)
threadLock1.release()

然后调用子类,开启各个子类实例化出来的thread, 把各个thread放进一个数组,数组分别调用 .join()

thread1 = myThread(rtr1)
thread2 = myThread(rtr2)
thread3 = myThread(srx) thread1.start()
thread2.start()
thread3.start() threads = []
threads.append(thread1)
threads.append(thread2)
threads.append(thread3) for t in threads:
t.join() print "All done"

然而并没有卵用,哪怕是你用了 .join让他们分别回归主线程,一会儿再说join()的事情。

  • 最后的解决办法
  • sys.stdout.write(a_string)

对,就是这个货,我从这个链接看到的,最后那个答案就是

原话如下

‘The issue is that python uses seperate opcodes for the NEWLINE printing and the printing of the object itself. The easiest solution is probably to just use an explicit sys.stdout.write with an explicit newline.’

然后下面有个评论是sys.stdout.write的用法

‘From my recent experience, this is absolutely true. I’m not exactly sure why it happens, but the printstatement (even when STDOUT is properly serialized and flushed) will output erratic newlines. You must usesys.stdout.write(s + ‘\n’) to avoid this. ‘

当然下面还有个评论是跟上面这位仁兄说依然需要lock的,但是anyway,这个sys.stdout.write(a_string)解决了我的问题

  • 最后的代码是这样的
  • 不使用自己定义的子类了,依然使用自带的threading.Thread()创建新thread
  thread1 = threading.Thread(target=printARP, args=[rtr1])
thread2 = threading.Thread(target=printARP, args=[rtr2])
thread3 = threading.Thread(target=printARP, args=[srx])

然后剩下的都一样

  • 唯一需要改动的地方

printARP这个功能模块,改成如下,把print改成sys.stdout.write() 记得引入sys

def printARP(device):
'''
print the ARP table on this device
'''
conn = ConnectHandler(**device)
#sys.stdout.flush() arp = conn.send_command("show arp")
time.sleep(1)
outp = ("ARP table on %s :" % get_name_of_obj(device, "each_device")+"\n")
# use find_prompt() to determin the output of threads are not messed up
outp += (conn.find_prompt()+"\n")
outp += (arp+"\n")
outp += "*********************\n"
sys.stdout.write(outp)

完整的代码在这里

线程的join

差点忘了说了,这个答主的答案特别好,那个图简直绝了

Python multi-thread 多线程 print 如何避免print的结果混乱的更多相关文章

  1. 【PYTHON】 Missing parentheses in call to 'print'

    Microsoft Windows [版本 10.0.15063] (c) 2017 Microsoft Corporation.保留所有权利. C:\Users\Jam>python Pyth ...

  2. python 并发编程 多线程 Thread对象的其他属性或方法

    介绍 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. threading模块提供的一些方法: ...

  3. python高级之多线程

    python高级之多线程 本节内容 线程与进程定义及区别 python全局解释器锁 线程的定义及使用 互斥锁 线程死锁和递归锁 条件变量同步(Condition) 同步条件(Event) 信号量 队列 ...

  4. python 类变量 在多线程下的共享与释放问题

    最近被多线程给坑了下,没意识到类变量在多线程下是共享的,还有一个就是没意识到 内存释放问题,导致越累越大 1.python 类变量 在多线程情况 下的 是共享的 2.python 类变量 在多线程情况 ...

  5. Python拾忆--多线程的socket服务器

    阳光明媚的午后,想想最近要开始从写Java到写Python了,就随手打开电脑来体验一下Python与Java之间的不同吧~ 记得我还在上大二的时候,那个时候才开始学Java,最感兴趣的就是Java书最 ...

  6. python中的多线程【转】

    转载自: http://c4fun.cn/blog/2014/05/06/python-threading/ python中关于多线程的操作可以使用thread和threading模块来实现,其中th ...

  7. Python之FTP多线程下载文件之分块多线程文件合并

    Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

  8. Python系列之多线程、多进程

    线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供 ...

  9. Python 简单理解多线程

    进程,是一个或多个线程的集合,每个进程在内存中是相对独立的. 线程,是计算机最小的运算单元,每个进程至少要有一个线程,多个线程时,每个线程间之间共享内存. 分别举例常规运行和多线程运行: 0)常规运行 ...

随机推荐

  1. CSS选择器、CSS hack及CSS执行效率

    主要内容: 1.CSS选择器.优先级与匹配原理 2. CSS 引入的方式有哪些 ? link 和 @import 的区别是 ? 3.CSS hack 4.如何书高效CSS  一.CSS选择器.优先级与 ...

  2. 错误:document.getElementById("userForm").submit();Object is not a function

    表单提交时发生的错误解决办法: 利用这种方法进行表单提交的时候,表单中的元素不能有 name="submit"的元素,否则该元素会与submit()方法造成混淆,导致错误!

  3. VS2010项目缺少组件

    遇到的问题是解决方案中部分项目无法加载, 提示需要缺少的web组件才能加载该项目,是否通过WEB安装组件来网络安装, 点击确定以后就什么也没有了. 网上查阅了一番,结合自己的使用情况(在家里用的是vs ...

  4. Spring MVC 学习总结(三)——请求处理方法Action详解

    Spring MVC中每个控制器中可以定义多个请求处理方法,我们把这种请求处理方法简称为Action,每个请求处理方法可以有多个不同的参数,以及一个多种类型的返回结果. 一.Action参数类型 如果 ...

  5. 15个前卫的 HTML5 & CSS3 网页设计作品

    今天,我们编译收集一组使用 HTML5 和 CSS3 制作的精美网站.在此集合中,你可以看到平面设计,网页设计,作品集和企业网站设计实例. 响应式设计和基于 HTML5 & CSS3 编码的网 ...

  6. Jeet – 先进,直观,灵活的 CSS 网格系统

    Jeet 是一个先进的,直观的 CSS 网格系统.通过使用预处理器的强大功能,我们现在可以通过实际分数(或者浮点数)来生成一个基于百分比宽度和间隔的网格.让你用更少的代码,更快的速度构建页面布局. 您 ...

  7. java中map插入相同的key

    测试用例: package test; import org.junit.Test; import po.Person; import java.util.HashMap; import java.u ...

  8. Elasticsearch入门介绍

    ES是一个高扩展的.开源的.全文检索的搜索引擎,它提供了近实时的索引.搜索.分析功能. ES文档翻译与总结参考:ES知识汇总 应用场景 1 它提供了强大的搜索功能,可以实现类似百度.谷歌等搜索. 2 ...

  9. 阅读《LEARNING HARD C#学习笔记》知识点总结与摘要四

    又是一个周末,刚好有时间,又继续复习与总结了,希望能让大家受益,不足之处欢迎指正,谢谢! 十八. Lambda 1.Lambda表达式:匿名方法的另一种表现形式,它可以包含表达式和语句,且用于创建委托 ...

  10. jQuery1.9及其以上版本中动态元素on绑定事件无效解决方案

    jQuery 1.9/2.0/2.1及其以上版本无法使用live函数了,然而jQuery 1.9及其以上版本提供了on函数来代替.本文讲解了jQuery on函数的使用方法,以及在使用jQuery函数 ...