一. python非阻塞编程的settimeout与setblocking+select

原文:www.th7.cn/Program/Python/201406/214922.shtml

侧面认证Python的settimeout确实应该是非阻塞,这次使用select+setblocking和settimeout来做个对比,以此来证明。

首先我设置socket为非阻塞的。然后使用select来监控套接字。

#!/usr/bin/env python
# encoding: utf-8
import socket
import threading
import Queue
import time
import select
class worker(threading.Thread):
    def __init__(self,name,queue):
        self.data=queue
        super(worker,self).__init__(name=name)
    def run(self):
        for i in range(10000):
            self.data.put(i) class customer(threading.Thread):
    def __init__(self,name,queue):
        super(customer,self).__init__(name=name)
        self.data=queue
    def scan(self,ip,port):
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.setblocking(False) #non_blocking
        #s.settimeout(0.1)
        results=s.connect_ex((ip,port))
        #print results
        a,b,c=select.select([],[s,],[s,],0.1)#设置超时时间0.1秒,这里我根据前面博文的总结得出来的。
        #当connect连接成功的时候,代表Tcp3次握手完成,此时变成可写状态
        if b:#如果socket可写,代表了端口是开放的
            print port
        s.close()
    def run(self):
        while True:
            try:
                a=self.data.get(1,5)
            except:
                break
            else:
                ip='220.181.136.241'
                self.scan(ip,a)
def main():
    start=time.time()
    queue=Queue.Queue()
    pool=[]
    worke=worker('firebroo',queue)
    worke.start()
    for i in range(100):
        a=customer('firebroo',queue)
        pool.append(a)
    for i in pool:
        i.start()
    worke.join()
    for i in pool:
        i.join()
    print time.time()-start
    del pool[:] if __name__=='__main__':
    main()

大概花费17.5秒执行完毕。下面我使用settimeout。

#!/usr/bin/env python# encoding: utf-8
import socket
import threading
import Queue
import time
import select
class worker(threading.Thread):
    def __init__(self,name,queue):
        self.data=queue
        super(worker,self).__init__(name=name)
    def run(self):
        for i in range(10000):
            self.data.put(i) class customer(threading.Thread):
    def __init__(self,name,queue):
        super(customer,self).__init__(name=name)
        self.data=queue
    def scan(self,ip,port):
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        #s.setblocking(False)
        s.settimeout(0.1)#为了和前面保持一致,当然得设置0.1秒
        results=s.connect_ex((ip,port))
        if results==0:#connect_ex中0代表端口开放,3次握手完成
            print port
        #print results
        #a,b,c=select.select([],[s,],[s,],0.1)#设置超时时间0.1秒,这里我根据前面博文的总结得出来的。
        #当connect连接成功的时候,代表Tcp3次握手完成,此时变成可写状态
        #if b:#如果socket可写,代表了端口是开放的
        #    print port
        s.close()
    def run(self):
        while True:
            try:
                a=self.data.get(1,5)
            except:
                break
            else:
                ip='220.181.136.241'
                self.scan(ip,a)
def main():
    start=time.time()
    queue=Queue.Queue()
    pool=[]
    worke=worker('firebroo',queue)
    worke.start()
    for i in range(100):
        a=customer('firebroo',queue)
        pool.append(a)
    for i in pool:
        i.start()
    worke.join()
    for i in pool:
        i.join()
    print time.time()-start
    del pool[:] if __name__=='__main__':
    main()

时间大概是17.4。这两个测试结果应该可以说是一样的,难免会有误差。

总结:由此我可以说Python的settimeout这个API确实是非阻塞。和select+setblocking效果是一样的

二. Python Queue的使用

原文:doudouclever.blog.163.com/blog/static/1751123102012111192621448/

python 中,队列是线程间最常用的交换数据的形式。Queue模块是提供队列操作的模块,虽然简单易用,但是不小心的话,还是会出现一些意外。

1. 阻塞模式导致数据污染

import Queue
       q = Queue.Queue(10)
       for i in range(10):
               myData = 'A'
               q.put(myData)
               myData = 'B'


是一段极其简单的代码,但我总是不能获得期望的结果(期望在队列中写入10个A,却总是混杂了B)。原来,Queue.put()默认有 block =
True 和 timeou 两个参数。当  block = True 时,写入是阻塞式的,阻塞时间由 timeou 
确定。正因为阻塞,才导致了后来的赋值污染了处于阻塞状态的数据。Queue.put()方法加上 block=False
的参数,即可解决这个隐蔽的问题。但要注意,非阻塞方式写队列,当队列满时会抛出 exception Queue.Full 的异常。

2. 无法捕获 exception Queue.Empty 的异常

while True:
                ......
                try:
                        data = q.get()
                except Queue.Empty:
                        break


的本意是用队列为空时,退出循环,但实际运行起来,却陷入了死循环。这个问题和上面有点类似:Queue.get()默认的也是阻塞方式读取数据,队列为
空时,不会抛出 except Queue.Empty ,而是进入阻塞直至超时。 加上block=False 的参数,问题迎刃而解。

3. Queue常用方法汇总

Queue.Queue(maxsize=0)   FIFO, 如果maxsize小于1就表示队列长度无限
       Queue.LifoQueue(maxsize=0)   LIFO, 如果maxsize小于1就表示队列长度无限
       Queue.qsize()   返回队列的大小
       Queue.empty()   如果队列为空,返回True,反之False
       Queue.full()   如果队列满了,返回True,反之False
       Queue.get([block[, timeout]])   读队列,timeout等待时间
       Queue.put(item, [block[, timeout]])   写队列,timeout等待时间
       Queue.queue.clear()   清空队列

python socket非阻塞及python队列Queue的更多相关文章

  1. Python Socket单线程+阻塞模式

    Python之旅]第五篇(二):Python Socket单线程+阻塞模式 python Socket单线程 Socket阻塞模式 串行发送 摘要:  前面第五篇(一)中的一个Socket例子其实就是 ...

  2. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  3. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  4. python 3.x 学习笔记16 (队列queue 以及 multiprocessing模块)

    1.队列(queue) 用法: import queue q = queue.Queue() #先进先出模式 q.put(1) #存放数据在q里 作用: 1)解耦    2)提高效率 class qu ...

  5. python学习笔记——multiprocessing 多进程组件-队列Queue

    1 消息队列 1.1 基本语法 消息队列:multiprocessing.Queue,Queue是对进程安全的队列,可以使用Queue实现对进程之间的数据传输:还有一个重要作用是作为缓存使用. Que ...

  6. python基本数据结构栈stack和队列queue

    1,栈,后进先出,多用于反转 Python里面实现栈,就是把list包装成一个类,再添加一些方法作为栈的基本操作. 栈的实现: class Stack(object): #初始化栈为空列表 def _ ...

  7. [b0027] python 归纳 (十二)_并发队列Queue的使用

    # -*- coding: UTF-8 -*- """ 学习队列 Queue 总结: 1. 队列可以设置大小,也可以无限大小 2. 空了,满了,读写时可以阻塞,也可以报错 ...

  8. python IO非阻塞模型

    server端 import socket sk = socket.socket() sk.bind(('127.0.0.1', 8010)) sk.setblocking(False) # sk.l ...

  9. python socket编程---从使用Python开发一个Socket示例说到开发者的思维和习惯问题

    今天主要说的是一个开发者的思维和习惯问题. 思维包括编程的思维和解决一个具体问题的分析思维,分析思路,分析方法,甚至是分析工具. 无论是好习惯还是不好的习惯,都是在者一天一天的思维中形成的.那些不好的 ...

随机推荐

  1. 【C语言项目】贪吃蛇游戏(下)

    目录 00. 目录 07. 游戏逻辑 7.5 按下ESC键结束游戏 7.6 判断是否撞到墙 7.7 判断是否咬到自己 08. 游戏失败界面设计 8.1 游戏失败界面边框设计 8.2 撞墙失败界面 8. ...

  2. vue父组件获取子组件页面的数组 以城市三级联动为例

    父组件调用子组件 <Cselect ref="registerAddress"></Cselect> import Cselect from '../../ ...

  3. js和JQuery中的获取宽、高、位置等方法整理

    1.获取当前窗口宽度区别(需要注意的是用的window还是document)JQuery:console.log($(window).width()); //获取窗口可视区域的宽度 console.l ...

  4. 如何用纯 CSS 绘制一个充满动感的 Vue logo

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/zaqKPx 可交互视频教 ...

  5. 常用模块之configpaser与shutil

    configparser模块 定义:configparser翻译为配置解析,即它是用来解析配置文件的 配置文件:用于编写程序的配置信息的文件 配置文件编写格式 配置文件中只允许出现两种类型的数据 se ...

  6. Python9-反射-day27(大年初三)

    复习 class 类名(父类,父类2): 静态属性 = '' #静态属性 类属性 def __init__(self): #初始化方法 self.name = 'alex' def func(self ...

  7. stm32开发套件选择——LL SPL HAL Snippets的应用范围

  8. ZZULIoj 1912 小火山的爱情密码

    Description 小火山获得了一个字符串,然而大火山让小火山从里面截取一段字符串,并且让小火山截取的字符串满足一些字符达到一定数量. 小火山觉得很容易,但是他想要知道他至少得截取多长的字符串. ...

  9. Spring,Mybatis,Springmvc框架整合项目(第一部分)

    一.说在前面的话 本篇博文实现一个注册登录小项目,使用spring,mybatis,springmvc框架进行整合,我们创建的是一个maven工程,主要是方便jar包版本的管理.项目使用eclispe ...

  10. Android开发——IntentFilter的匹配规则

    1.  IntentFilter中的过滤信息 启动Activity分为显式调用和隐式调用,前者没什么好讲的,后者需要Intent能够匹配目标组件的IntentFilter中所设置的过滤信息.包括act ...