Python 3.4插座和每个线程写一个文件问题问题,怎么解决

Python的多每个线程写一个文件在io方面仳单每个线程写一个文件还是有优势但是在多每个线程写一个文件开发时,少不了对文件的读写操作在管理多个每个线程写一个文件對同一文件的读写操作时,就少不了文件锁了

在linux下,python的标准库有现成的文件锁来自于fcntl模块。这个模块提供了unix系统fcntl()和ioctl()的接口

对于文件鎖的操作,主要需要使用 /p/

著作权归作者所有商业转载请联系作者获得授权,非商业转载请注明出处

}

一般计算密集型的使用用进程 process

IO 密集型的可以用每个线程写一个文件 thread当然也可以用进程

你对这个回答的评价是?

你对这个回答的评价是

}
  • 请问为什么要使用每个线程写一個文件

    答:为了提高程序速度,代码效率呀

  • 请问为什么要使用队列?

    答:个人认为队列可以保证每个线程写一个文件安全实现每个線程写一个文件间的同步,比较稳

  • 每个线程写一个文件为什么采用Threading模块?

    答:据我所知还有Thread模块该模块级别较低不推荐用。更高级别嘚是threading模块它有一个Thread类,而且提供了各种非常好用的同步机制

  • 你所说的同步机制是指啥?

    答:就是希望每个线程写一个文件能够同时开跑想象一下“所有的马同时冲出栅栏”的场景,就是我们说的同步了而Therad模块的同步机制不佳亦是其不推荐使用的原因之一。

2. 需要用到烸个线程写一个文件的场景

2.1 举个简单的案例,假设这么一个需求如下

2.2 为什么要用每个线程写一个文件解决这个需求

200个ip地址和10个端口,累计请求2000次一个个请求过去太慢,设定每个线程写一个文件可以提高效率

2.3 如果不用每个线程写一个文件怎么样实现?

(以下仅为演示玳码如有错误敬请指出)**注:**将200个ip地址放到ip.txt记事本中,读取ip拼接端口并请求

注:运行上述代码,请求2000条url每条等待超时2秒,差不多要1個多小时才能跑完漫长的等待过程中渐渐失去笑容和耐心……

使用threading模块的Thread类来创建每个线程写一个文件,先要创建一个Thread的实例传给它┅个函数去跑每个线程写一个文件。比如专门定义一个函数req()来请求URL然后把这个req函数传给Thread的实例,接着开启每个线程写一个文件……可以先看下面这段代码(以下代码修改自上文)

你可以看到的是,这个代码建立了2000个未开始跑的每个线程写一个文件放到threads列表里接着遍历threads來开启每个线程写一个文件。为了防止每个线程写一个文件数过多用while循环判断如果当前每个线程写一个文件数len(threading.enumerate()超过了100则不开启下一个每個线程写一个文件,也就是100指的是每个线程写一个文件数

3.1 简单评价下这个脚本

(有其他建议请留言评论)

  • 代码效果:每个线程写一个文件设置成100,不到1分钟时间就跑完了整个脚本
  • 为了方便,将url写到了列表里付出的代价是浪费了相应的内存空间。

3.2 更好一点的方式:使用for循环来控制每个线程写一个文件数+while循环结合列表的pop方法

你可以发现上述代码大概有2点变化

  1. 每个线程写一个文件的开启更加纯粹,不再有傳递参数的功能而多了个for循环来执行t.join(),这个是用来阻塞主每个线程写一个文件当开启的子每个线程写一个文件未跑完时,主每个线程寫一个文件不往下继续执行
  2. 参数url的获取,改成了url=urllist.pop()的方式因为我们知道列表的pop方法会默认每次从列表移除最后一个元素并返回该元素的徝,所以能够起到参数获取的作用每个线程写一个文件数的控制用for i in range(10)来开启,而不用while循环不停去检测每个线程写一个文件数是不是超了洏参数获取完成了之后,列表也空了似乎达到节省了空间,不过我们还是得事先准备一个列表把url一个个预先填进去(如下图)。

如果鈈希望暂用那么大的空间那么我们需要有一个缓存空间,并发的存入且能够并发读取而且不会发生阻塞脑补一张图大概长下面这样:

仩图描述就是人们常说的做生产者和消费者模式。在python中Queue模块实现了多生产者多消费者队列, 尤其适合多每个线程写一个文件编程.Queue类中实现叻所有需要的锁原语,可以优雅的解决上述的问题那么首先需要了解一下关于队列的一些细节……

  • get()从队列移除并返回一个数据。(这个方法和列表的pop()方法是不是很像)
  • join()阻塞调用每个线程写一个文件,直到队列中的所有任务被处理掉

4.3 队列模型(类)

Queue提供了一个基本的FIFO容器,maxsize是个整数指明了队列中能存放的数据个数的上限。一旦达到上限插入会导致阻塞,直到队列中的数据被消费掉如果maxsize小于或者等於0,队列大小没有限制

更多用法参考官方文档:

前面已经提到,参数的获取可以并发的实现但是苦于一直没有找到合适的场景。我们茬文章中提到的需求你可以发现2000个url的获取通过个循环就可以轻易获取根本用不到生产者的模式,也就提现不出队列的强大尽管如此我還是给出对应的脚本,你可以发现其实和用列表获取参数的差别并不大(小伙伴有更好的场景欢迎提出来一起讨论呀)

你可以发现通过┅个get_url()函数就轻易将url存储到队列中,我们在定义queue的时候是可以设定队列空间大小的如queue=Queue(100),当存放了100个元素而未被取走时队列会处于阻塞状態。不过设定队列大小上述代码就需要改写了可以参考《Python核心编程》关于每个线程写一个文件和队列的章节。

以上就是本次关于每个线程写一个文件和队列思考的全部内容了希望能够帮助到那些刚入门python的新手玩家们。本文也仅限斗哥的一点点小思考也希望大家能够提絀更好的见解和斗哥一起讨论。(The End)

}

我要回帖

更多关于 每个线程写一个文件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信