多进程

在使用多线程并没有实质性的提速后,果断放弃了多线程;最后还是使用多进程的方式处理这个50G的大文件

多线程和多进程区别

一. 两者区别 进程是分配资源的基本单位;线程是系统调度和分派的基本单位。 属于同一进程的线程,堆是共享的,栈是私有的。 属于同一进程的所有线程都具有相同的地址空间。

多进程的优点:

①编程相对容易;通常不需要考虑锁和同步资源的问题。 ②更强的容错性:比起多线程的一个好处是一个进程崩溃了不会影响其他进程。 ③有内核保证的隔离:数据和错误隔离。 对于使用如C/C++这些语言编写的本地代码,错误隔离是非常有用的:采用多进程架构的程序一般可以做到一定程度的自恢复;(master守护进程监控所有worker进程,发现进程挂掉后将其重启)。

多线程的优点:

①创建速度快,方便高效的数据共享 共享数据:多线程间可以共享同一虚拟地址空间;多进程间的数据共享就需要用到共享内存、信号量等IPC技术。 ②较轻的上下文切换开销 - 不用切换地址空间,不用更改寄存器,不用刷新TLB。 ③提供非均质的服务。如果全都是计算任务,但每个任务的耗时不都为1s,而是1ms-1s之间波动;这样,多线程相比多进程的优势就体现出来,它能有效降低“简单任务被复杂任务压住”的概率。

1.文件分块类

通过初始化一个文件分块类,并调用partion函数,获得每个进程所需要读取的区间

pos_list = PartitionFile(fileName, ProcessNum).partion() # *存放所有文件指针坐标*

class PartitionFile(object):
    def __init__(self, fileName, jobsNum):
        self.fileName = fileName
        self.blockNum = jobsNum

    def partion(self):
        fd = open(self.fileName, 'r')
        fd.seek(0, 2)  # 移动文件指针到文件尾,用于获取文件大小
        fileSize = fd.tell()  # 获取文件字符数
        Pos_list = []  # 指针坐标,数组
        blockSize = int(fileSize/self.blockNum)
        start_Pos = 0  # 文件初始指针
        for i in range(self.blockNum):
            if i == self.blockNum-1:
                end_Pos = fileSize-1  # 最后一个文件区块为文件结尾
                Pos_list.append((start_Pos, end_Pos))
                break
            end_Pos = start_Pos+blockSize-1  # 均匀分配每个区块
            Pos_list.append((start_Pos, end_Pos))
            start_Pos = end_Pos+1  # 下一个区块的开始坐标
        fd.close()
        return Pos_list

2.读取进程

因为python中字典和列表都是引用类型数据,所以使用函数对其直接操作,可以改变原字典;这里只有文件的读取,不涉及子进程间的通信,所以不使用Queue

  • 进程类中定义一个self.outData用于存储每行结果

  • processFunction函数会对每行结果进行处理后存进self.outData

子进程写入文件

这里没有直接使用生产者-消费者模型,是因为基本没有子进程间的通信;只有主进程和子进程的通信;我当时还直接将所有的子进程读到的文件数据写入Queue,然后再从主进程中读取,结果最后子进程一直被挂起了。原因可能是,队列容量达到系统上限,生成者太多了,消费者只有主进程一个

参考:https://www.zhihu.com/question/63265466

  • 遍历self.outData数据,将结果写入文件

  • 由于涉及到多个进程对文件的写,这里使用了文件锁

  • 将写入的文件名通过Queue传递给主进程

3.排序进程

  • 排序进程的文件名是,主进程从队列中获取得到的

4.封装后的函数

  • 主进程通过队列的方式从子进程中获取染色体编号

5.性能测试

  • 单进程

  • 四个进程·

6.源代码

https://github.com/BiocottonHub/zpliuCode/blob/master/Hi-c/HiCProTojuicer.py

7.参考

Last updated

Was this helpful?