python多线程分块读文件

最近涉及到一个利用python分块读文件的需求,一开始想法觉得很简单,就对一个文件取总行数,获得线程数、每个线程获得对应的行范围、各线程独立去读自己的范围内的内容即可。

实际操作下来发现有问题,读出来的内容总是有些小错误,怀疑不是这么简单,同一个文件的句柄估计多线程同时操作不安全。网上查阅了资料https://blog.csdn.net/lingerlanlan/article/details/45699931也有我类似的问题,采用了文中第二种方法实现即thread + queue来实现多线程分块读文件。

直接上代码,代码很简单,亲测没有bug。

import threading
import ConfigParser
import url_func
import sys
import Queue


class Reader(threading.Thread):
    def __init__(self, thread_id):
        super(Reader, self).__init__()
        self.thread_id = thread_id

    def run(self):
        global q

        temp_list = q.get()

        for text in temp_list:
            columns = text.split('\001')
            if len(columns) == 8:
                #取出线程对应文件内容后的文件操作,可忽略
                url_func.url_make_open(a_o_b, plat_form, self.thread_id, columns)


class Partition(object):
    def __init__(self, file_name, thread_num):
        self.file_name = file_name
        self.block_num = thread_num

    #按照线程数对文件进行分块并存进queue中
    def part_and_queue(self):
        pos_list = []
        #文件总行数
        file_size = url_func.file_lines(self.file_name)
        #按照线程数分成对应块的大小
        block_size = file_size / self.block_num
        start_pos = 0
        global q

        for i in range(self.block_num):
            if i == self.block_num - 1:
                end_pos = file_size - 1
                pos_list.append((start_pos, end_pos))
                break
            end_pos = start_pos + block_size - 1
            if end_pos >= file_size:
                end_pos = file_size - 1
            if start_pos >= file_size:
                break
            pos_list.append((start_pos, end_pos))
            start_pos = end_pos + 1

        #读取每块内容存进queue中
        fd = open(self.file_name, 'r')
        for pos_tu in pos_list:
            temp_text = []
            start = pos_tu[0]
            end = pos_tu[1]

            while start <= end:
                text = fd.readline().strip('\n')
                temp_text.append(text)
                start = start + 1

            q.put(temp_text)
        fd.close()


if __name__ == '__main__':
    
    config = ConfigParser.ConfigParser()
    config.readfp(open('config'))
    file_name = sys.argv[1]
    plat_form = sys.argv[2]
    a_o_b = sys.argv[3]

    #线程数量可配
    thread_num = int(config.get('info', 'threadNum'))
    q = Queue.Queue()
    p = Partition(file_name, thread_num)
    t = []
    p.part_and_queue()

    for i in range(thread_num):
        t.append(Reader(i))
    for i in range(thread_num):
        t[i].start()
    for i in range(thread_num):
        t[i].join()

解释一下,主线程首先将文件分块分别读取之后存进queue中,queue 本身是线程安全的,启动子线程分别从queue中取相应的内容来进行后续的操作

你可能感兴趣的:(python多线程分块读文件)