一. 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. uaf-湖湘杯2016game_学习

    0x00 分析程序 根据分析,我们可以得到以下重要数据结构 0x01 发现漏洞 1.在武器使用次数耗光后,程序会把存储该武器的堆块free,在free的时候没有清空指针,造成悬挂指针 2.commen ...

  2. Js自学学习-笔记6-8

    <!-- 第6-7课笔记 --> <!-- for循环 for(条件1:判断:变化)其实就是if嵌套 while do for循环简化版 可以用do while swith case ...

  3. ios之UISlider

    初始化一个Slider   UISlider *slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 400,320 , 20)]; 滑块是一个标 ...

  4. c++ 计算彩票中奖概率

    操作方法: 输入两个数字,第一个数字是备选总数,第二个数字是选择总数,然后返回中将概率. 可以投注多次,结束的时候返回总的中将概率. #include <iostream> using n ...

  5. javascript 使用 load 和 unload 事件,解决浏览器打开和关闭时需要做的操作。

    最近有一个业务,就是修改一个业务需要加上锁.也就是打开浏览器时,加锁.等用户操作完毕,关掉浏览器之后在把锁打开.一开始想问题很局限.只是想着,关闭浏览器解锁,刷新页面不做操作.然后就一直在找在调用un ...

  6. LeetCode(96) Unique Binary Search Trees

    题目 Given n, how many structurally unique BST's (binary search trees) that store values 1-n? For exam ...

  7. Python开发:网络编程

    Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别的网络 ...

  8. linux -- 查找(find)命令 一

    find: find命令是非常有用的linux命令,我们可以用它来根据指定的搜索条件来搜索整个文件系统来查找文件或目录. 基本的‘find file’命令 find . -name "foo ...

  9. 一丶Python模块之getpass模块

    Python模块之getpass模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. getpass模块提供了可移 ...

  10. 九度oj 题目1185:特殊排序

    题目描述: 输入一系列整数,将其中最大的数挑出,并将剩下的数进行排序. 输入: 输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数. 接下来的一行有N个整数. 输出: 可能 ...