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)應用也需要啟動單獨的線程,從主機環境中收集用戶界面事件……總之,多線程在實際編程中的應用是非常廣泛的。