python多线程写文件
1. python读取大文件处理时使用多线程
如果有个很大的文件,几十G?,需要每次读取一部分,处理后再读取剩余部分。
with open as f 已经从内部处理难点,使用 for line in f 以迭代器的形式每次读取一行,不态陆猜会有内存问题。
下面程序的思路是用一个列表存放读取到的数据悉迅,达到长度后就开始处理,处理帆型完就清空列表,继续执行
2. Python多线程是什么意思
简单地说就是作为可能是仅有的支持多线程的解释型语言(perl的多线程是残疾,PHP没有多线程),Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode。
UPDATE:如评论指出,Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的。
如果你的代码是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有context switch
但是:如果你的代码是IO密集型,多线程可以明显提高效率。例如制作爬虫(我就不明白为什么Python总和爬虫联系在一起…不过也只想起来这个例子…),绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行。
反过来讲:你就不应该用Python写CPU密集型的代码…效率摆在那里…
如果确实需要在CPU密集型的代码里用concurrent,就去用multiprocessing库。这个库是基于multi process实现了类multi thread的API接口,并且用pickle部分地实现了变量共享。
再加一条,如果你不知道你的代码到底算CPU密集型还是IO密集型,教你个方法:
multiprocessing这个mole有一个mmy的sub mole,它是基于multithread实现了multiprocessing的API。
假设你使用的是multiprocessing的Pool,是使用多进程实现了concurrency
from multiprocessing import Pool
如果把这个代码改成下面这样,就变成多线程实现concurrency
from multiprocessing.mmy import Pool
两种方式都跑一下,哪个速度快用哪个就行了。
UPDATE:
刚刚才发现concurrent.futures这个东西,包含ThreadPoolExecutor和ProcessPoolExecutor,可能比multiprocessing更简单
3. python多线程输入的问题
在对文件进行预处理的时候,由于有的文件有太大,处理很慢,用python处理是先分割文件,然后每个文件起一个线程处理,启了10个线程,结果还比不起线程慢一些,改成多进程之后就好了.
使用multiprocessing模块实现真正的并发
因为GIL会序列化线程, Python中的多线程不能在多核机器和集群中加速. 因此Python提供了multiprocessing模块, 可以派生额梁派培外的进程代替线程, 跳出GIL的限制. 此外, 你也可以在外部C代码中结合该建议, 使得程序更快.
注意, 进程的开销通常比线程昂贵, 因为线程自动共享内存地址空间和文件描述符. 意味着, 创建进程比创建线程会花费更多, 也可能花费更多内存. 这点在你计算使用多处理器时要牢记.
理解Python的GIL(全局解释器锁):
GIL是必要的,因为CPython的内存管理是非线程安全的。你不能简单地创建多个线程羡闹,并希望Python能在多核心的机器上运行得更快。这是因为 GIL将会防止多个原生线程同时执行Python字节码。换句话说,GIL将序列化您的所有线程。然而,您可以使用线程管理多个派生进程加速程序,这些程 序独立橡唯的运行于你的Python代码外。
4. python循环怎么用多线程去运行
背景:Python脚本:读取文件中每行,放入列表中;循环读取列表中的每个元素,并做处理操作。
核心:多线程处理单个for循环函数调用
模块:threading
第一部分:
:多线程脚本 (该脚本只有两个线程,t1循环次数<t2)#!/usr/bin/env python#-*- coding: utf8 -*- import sysimport timeimport stringimport threadingimport datetimefileinfo = sys.argv[1] # 读取文件内容放入列表host_list = []port_list = [] # 定义函数:读取文件内容放入列表中def CreateList(): f = file(fileinfo,'r') for line in f.readlines(): host_list.append(line.split(' ')[0]) port_list.append(line.split(' ')[1]) return host_list return port_list f.close() # 单线程 循环函数,注释掉了#def CreateInfo(): # for i in range(0,len(host_list)): # 单线程:直接循环列表# time.sleep(1)# TimeMark = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')# print "The Server's HostName is %-15s and Port is %-4d !!! [%s]" % (host_list[i],int(port_list[i]),TimeMark)# # 定义多线程循环调用函数def MainRange(start,stop): #提供列表index起始位置参数 for i in range(start,stop): time.sleep(1) TimeMark = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') print "The Server's HostName is %-15s and Port is %-4d !!! [%s]" % (host_list[i],int(port_list[i]),TimeMark) # 执行函数,生成列表CreateList()# 列表分割成:两部分 mid为列表的index中间位置mid = int(len(host_list)/2) # 多线程部分threads = []t1 = threading.Thread(target=MainRange,args=(0,mid))threads.append(t1)t2 = threading.Thread(target=MainRange,args=(mid,len(host_list)))threads.append(t2) for t in threads: t.setDaemon(True) t.start()t.join()print "ok"
以上是脚本内容!!!
----------------------------------------------------------------------
:读取文件的内容
文件内容:
[root@monitor2 logdb]# cat hostinfo.txt
192.168.10.11 1011
192.168.10.12 1012
192.168.10.13 1013
192.168.10.14 1014
192.168.10.15 1015
192.168.10.16 1016
192.168.10.17 1017
192.168.10.18 1018
192.168.10.19 1019
192.168.10.20 1020
192.168.10.21 1021
192.168.10.22 1022
192.168.10.23 1023
192.168.10.24 1024
192.168.10.25 1025
:输出结果:
单线程 : 执行脚本:输出结果:
[root@monitor2 logdb]# ./Threadfor.py hostinfo.txt
The Server's HostName is 192.168.10.10 and Port is 1010 !!! [2017-01-10 14:25:14]
The Server's HostName is 192.168.10.11 and Port is 1011 !!! [2017-01-10 14:25:15]
The Server's HostName is 192.168.10.12 and Port is 1012 !!! [2017-01-10 14:25:16]
.
.
.
The Server's HostName is 192.168.10.25 and Port is 1025 !!! [2017-01-10 14:25:29]
多线程:执行脚本:输出 结果
[root@monitor2 logdb]# ./Threadfor.py hostinfo.txt
The Server's HostName is 192.168.10.11 and Port is 1011 !!! [2017-01-10 14:51:51]
The Server's HostName is 192.168.10.18 and Port is 1018 !!! [2017-01-10 14:51:51]
The Server's HostName is 192.168.10.12 and Port is 1012 !!! [2017-01-10 14:51:52]
The Server's HostName is 192.168.10.19 and Port is 1019 !!! [2017-01-10 14:51:52]
The Server's HostName is 192.168.10.13 and Port is 1013 !!! [2017-01-10 14:51:53]
The Server's HostName is 192.168.10.20 and Port is 1020 !!! [2017-01-10 14:51:53]
The Server's HostName is 192.168.10.14 and Port is 1014 !!! [2017-01-10 14:51:54]
The Server's HostName is 192.168.10.21 and Port is 1021 !!! [2017-01-10 14:51:54]
The Server's HostName is 192.168.10.15 and Port is 1015 !!! [2017-01-10 14:51:55]
The Server's HostName is 192.168.10.22 and Port is 1022 !!! [2017-01-10 14:51:55]
The Server's HostName is 192.168.10.16 and Port is 1016 !!! [2017-01-10 14:51:56]
The Server's HostName is 192.168.10.23 and Port is 1023 !!! [2017-01-10 14:51:56]
The Server's HostName is 192.168.10.17 and Port is 1017 !!! [2017-01-10 14:51:57]
The Server's HostName is 192.168.10.24 and Port is 1024 !!! [2017-01-10 14:51:57]
The Server's HostName is 192.168.10.25 and Port is 1025 !!! [2017-01-10 14:51:58]
5. python多线程有什么作用
线程在程序中是独立的、并发的执行流。与分隔的进程相比,进程中线程之间的隔离程度要小,它们共享内存、文件句柄和其他进程应有的状态。
因为线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程比进程具有更高的性能,这是由于同一个进程中的线程都有共性多个线程共享同一个进程的虚拟空间。线程共享的环境包括进程代码段、进程的公有数据等,利用这些共享的数据,线程之间很容易实现通信。
操作系统在创建进程时,必须为该进程分配独立的内存空间,并分配大量的相关资源,但创建线程则简单得多。因此,使用多线程来实现并发比使用多进程的性能要高得多。
总结起来,使用多线程编程具有如下几个优点:
进程之间不能共享内存,但线程之间共享内存非常容易。
操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此,使用多线程来实现多任务并发执行比使用多进程的效率高。
Python语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了 Python 的多线程编程。
在实际应用中,多线程是非常有用的。比如一个浏览器必须能同时下载多张图片;一个 Web 服务器必须能同时响应多个用户请求;图形用户界面(GUI)应用也需要启动单独的线程,从主机环境中收集用户界面事件……总之,多线程在实际编程中的应用是非常广泛的。
6. 多线程文件写同一个文件写不进去
这可能是由于多线程同时访问同一个文件导致的写入冲突问题。为了避免这个问题,您可以滚滚使用一些常见的解决方案:
1. 使用文件锁定:在每次写文件时请求文件锁定,确保同一时间只有一个线程可以写入数据。
2. 对写操作进行序列化:通过将写操作集中到一个线程中,避免多个线程同时写入同一个文件,从而避免冲突。
3. 确保写操作的原子性:使用特殊的写操作来确保所有的写入都是不可分割的,以避免出现冲突。
4. 使用专门的文件写入工具:使用专门的文件写入工具,例如 log4cxx,它可以处理多线程写入同一个文件的情况,并且能够保证性能和正确性。
总之,为了避免多线程写同一个文件导致的冲突问题,您需要选择适当的解决方案,根据具体情况大世余进行调整和返茄优化。
7. 日志文件太大,python怎么分割文件,多线程操作
python的多线程为伪多线程,多线程并不能提高文件IO的速度,在读取文件时使用直接读取 for line in open('文件名', 'r') 效率最高,因为此方式为直接读取,不像其它方式要把文件全部加载到内存再读取,所以效率最高。分割时文件时,提前计算好行数,把读取的每固定数量的行数存入新文件,直接读取完成,最后删除旧文件,即可实现文件分割。
示意代码:
line_count=0
index=0
fw=open('part'+str(index)+'.log','w')
forlineinopen('filename.log','r'):
fw.write(line)
line_count+=1
#假设每10000行写一个文件
ifline_count>10000:
fw.close()
index+=1
fw=open('part'+str(index)+'.log','w')
fw.close()
8. python 多线程爬取网站数据利用线程池
"""
@author: wangxingchun
多线程(线程池)
下载数据
"""
import requests
import csv
from concurrent.futures import ThreadPoolExecutor as tp
#创建一个csv文件,注意创建writer对象"csv.writer()"
f = open('xinfadi.csv','w',encoding='utf8')
csvwrite = csv.writer(f)
#如果写入txt文件,不需要创建writer对象。
# f = open('xinfadidata.txt','w',encoding='utf8')
#创建一个函数,以页码或基芹做为参数
def down(n_page):
url = 'http://www.xinfadi.com.cn/getPriceData.html'
data = {'锋销count': 428225,'current': n_page,'limit': 20}
resp = requests.post(url,data=data)
datas =resp.json()
#通过分析数据嵌套情况,获取数据。此处可在网页开发工具json数据中查看分析。
for i in range(len(datas['list'])):
name = datas['list'][i]['prodName']
highPrice = datas['list'][i]['highPrice']
lowPrice = datas['list'][i]['lowPrice']
pubDate = datas['list'][i]['pubDate']
place = datas['list'][i]['place']
csvwrite.writerow((name,highPrice,lowPrice,pubDate,place))#writerow要求写入的是可迭代对象
# f.writelines(f'{name},{highPrice},{lowPrice},{pubDate},{place} ')
resp.close()
if __name__ == '__main__':
with tp(50) as t: #创建线程池,
for n in range(1,101): #遍衫毕历数据网页
t.submit(down,n) #提交给线程池,进行多线程下载
print(f'共{n}页数据下载完毕!')
f.close()
9. python多线程
有很多的场景中的事情是同时进行的,比如开车的时候,手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的
结果:
• _thread
• threading(推荐使用)
结果:
threading.enumerate() 可查看当前正在运行的线程
结果:
结果:
结果:
结果: 出现资源竞争导致计算结果不正确
(1)当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
(2)线程同步能够保证多个线程安全访问资源,最简单的同步机制是引入互斥锁
(3)互斥锁为资源引入一个状态: 锁定/非锁定
(4)某个线程要更爱共享数据时,先将其锁定,此时资源的状态为"锁定", 其他线程不能更改;直到该线程释放资源,将资源状态变为"非锁定"
(5)互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性
结果: 计算正确
结果:卡住了
在线程间共享多个资源的时候,如果两个线程分别战友一部分资源且同时等待对方资源,就会造成死锁
(1)程序设计时避免(银行家算法)
(2)添加超时时间
10. 什么是线程(多线程),Python多线程的好处
几乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每一个运行中的程序就是一个进程。当一个程序运行时,内部可能包含多个顺序执行流,每一个顺序执行流就是一个线程。
线程和进程
几乎所有的操作系统都支持进程的概念,所有运行中的任务通常对应一个进程(Process)。当一个程序进入内存运行时,即变成一个进程。进程是处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个独立单位。
一般而言,进程包含如下三个特征:
独立性:进程是系统中独立存在的实体,它可以拥有自己的独立的资源,每一个进程都拥有自己的私有的地址空间。在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。
动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念。进程具有自己的生命周期和各种不同的状态,在程序中是没有这些概念的。
并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响。
并发(Concurrency)和并行(Parallel)是两个概念,并行指在同一时刻有多条指令在多个处理器上同时执行;并发才旨在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。
大部分操作系统都支持多进程并发执行,现代的操作系统几乎都支持同时执行多个任务。例如,程序员一边开着开发工具在写程序,一边开着参考手册备查,同时还使用电脑播放音乐……除此之外,每台电脑运行时还有大量底层的支撑性程序在运行……这些进程看上去像是在同时工作。
但事实的真相是,对于一个 CPU 而言,在某个时间点它只能执行一个程序。也就是说,只能运行一个进程,CPU 不断地在这些进程之间轮换执行。那么,为什么用户感觉不到任何中断呢?
这是因为相对人的感觉来说,CPU 的执行速度太快了(如果启动的程序足够多,则用户依然可以感觉到程序的运行速度下降了)。所以,虽然 CPU 在多个进程之间轮换执行,但用户感觉到好像有多个进程在同时执行。
现代的操作系统都支持多进程的并发执行,但在具体的实现细节上可能因为硬件和操作系统的不同而采用不同的策略。比较常用的策略有:
共用式的多任务操作策略,例如 Windows 3.1 和 Mac OS 9 操作系统采用这种策略;
抢占式的多任务操作策略,其效率更高,目前操作系统大多采用这种策略,例如 Windows NT、Windows 2000 以及 UNIX/Linux 等操作系统。
多线程则扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务。线程(Thread)也被称作轻量级进程(Lightweight Process),线程是进程的执行单元。就像进程在操作系统中的地位一样,线程在程序中是独立的、并发的执行流。
当进程被初始化后,主线程就被创建了。对于绝大多数的应用程序来说,通常仅要求有一个主线程,但也可以在进程内创建多个顺序执行流,这些顺序执行流就是线程,每一个线程都是独立的。
线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源。因为多个线程共享父进程里的全部资源,因此编程更加方便;但必须更加小心,因为需要确保线程不会妨碍同一进程中的其他线程。
线程可以完成一定的任务,可以与其他线程共享父进程中的共享变量及部分环境,相互之间协同未完成进程所要完成的任务。
线程是独立运行的,它并不知道进程中是否还有其他线程存在。线程的运行是抢占式的,也就是说,当前运行的线程在任何时候都可能被挂起,以便另外一个线程可以运行。
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发运行。
从逻辑的角度来看,多线程存在于一个应用程序中,让一个应用程序可以有多个执行部分同时执行,但操作系统无须将多个线程看作多个独立的应用,对多线程实现调度和管理,以及资源分配。线程的调度和管理由进程本身负责完成。
简而言之,一个程序运行后至少有一个进程,在一个进程中可以包含多个线程,但至少要包含一个主线程。
归纳起来可以这样说,操作系统可以同时执行多个任务,每一个任务就是一个进程,进程可以同时执行多个任务,每一个任务就是一个线程。
多线程的好处
线程在程序中是独立的、并发的执行流。与分隔的进程相比,进程中线程之间的隔离程度要小,它们共享内存、文件句柄和其他进程应有的状态
因为线程的划分尺度小于进程,使得多线程程序的并发性高。进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
线程比进程具有更高的性能,这是由于同一个进程中的线程都有共性多个线程共享同一个进程的虚拟空间。线程共享的环境包括进程代码段、进程的公有数据等,利用这些共享的数据,线程之间很容易实现通信。
操作系统在创建进程时,必须为该进程分配独立的内存空间,并分配大量的相关资源,但创建线程则简单得多。因此,使用多线程来实现并发比使用多进程的性能要高得多。
总结起来,使用多线程编程具有如下几个优点:
进程之间不能共享内存,但线程之间共享内存非常容易。
操作系统在创建进程时,需要为该进程重新分配系统资源,但创建线程的代价则小得多。因此,使用多线程来实现多任务并发执行比使用多进程的效率高。
Python 语言内置了多线程功能支持,而不是单纯地作为底层操作系统的调度方式,从而简化了 Python 的多线程编程。
在实际应用中,多线程是非常有用的。比如一个浏览器必须能同时下载多张图片;一个 Web 服务器必须能同时响应多个用户请求;图形用户界面(GUI)应用也需要启动单独的线程,从主机环境中收集用户界面事件……总之,多线程在实际编程中的应用是非常广泛的。