1. 程式人生 > >Python 多執行緒分塊讀檔案

Python 多執行緒分塊讀檔案

這裡參考了這篇文章 https://gist.github.com/friskfly/4412375 ,然後加上自己的理解和應用, 整理如下: 

# -*- coding: utf-8 -*-
import os,time
import threading
import ConfigParser
rlock = threading.RLock()

curPosition = 0  #初始化位置為檔案其實位置

class Reader(threading.Thread):
    def __init__(self, res):
        self.res = res
        super(Reader, self).__init__() #呼叫子類建構函式獲得檔案大小
    def run(self): #執行緒函式
        global curPosition
        fstream = open(self.res.fileName, 'r') #開啟檔案
        while True:
            rlock.acquire()
            startPosition = curPosition  #每次更新起始位置
            if(startPosition + self.res.fileSize/threadNum) < self.res.fileSize:   # 這裡,例如開了10個執行緒,就將檔案分為10塊,每個執行緒負責一塊
                curPosition = endPosition = (startPosition + self.res.fileSize/threadNum) 
            else:
                curPosition = endPosition = self.res.fileSize
            rlock.release()
            
            if startPosition == self.res.fileSize: 
                break
            elif startPosition != 0:        #這種情況適用於除了第一個檔案塊之後的檔案塊,因為分割後,第一塊以後的檔案塊的起始位置肯定比0大
                fstream.seek(startPosition) #找到那個位置
                line = fstream.readline()   #由於這一行在上一個迴圈中已經讀取了,所以先讀一行,把這行跳過
            pos = fstream.tell()            #獲取當前的位置
            while pos <= endPosition:          
                line = fstream.readline()
                '''
                    對每一行進行處理
                '''
                pos = fstream.tell()   #每處理一行,更新座標
                if pos ==self.res.fileSize:  #如果讀到了檔案末尾,跳出迴圈
                    break
        fstream.close()
 
class Resource(object):
    def __init__(self, fileName):
        self.fileName = fileName
        self.getFileSize()
    #計算檔案大小
    def getFileSize(self):
        fstream = open(self.fileName, 'r')
        fstream.seek(0, 2) #這裡0代表檔案開始,2代表檔案末尾
        self.fileSize = fstream.tell()
        fstream.close()
 
if __name__ == '__main__':

    #讀取配置檔案,配置檔案裡面可以寫一些檔案的資訊,這樣方便修改
    config = ConfigParser.ConfigParser()
    config.readfp(open('conf.ini'))
    fileName = config.get("info","fileRead")
    starttime = time.clock()
    #執行緒數
    threadNum = int(config.get("info","threadNum"))
    #檔案
    res = Resource(fileName)
    threads = []
    #初始化執行緒
    for i in range(threadNum):
        rdr = Reader(res)
        threads.append(rdr)
    #開始執行緒
    for i in range(threadNum):
        threads[i].start()
    #結束執行緒
    for i in range(threadNum):
        threads[i].join()
 
    print(time.clock() - starttime)
    fo.close()

配置檔案程式碼:

[info]
threadNum = 10
fileRead = input_file