python实现多进程工资计算器

介绍

优化上一个挑战中的计算器,支持使用多进程的方式对员工工资数据进行处理,以应对文件数据量很大的情况下,提高计算效率。

程序的执行过程如下,注意配置文件和输入的员工数据文件需要你自己创建并填入数据,可以参考上述的内容示例:

执行成功不需要输出信息到屏幕,执行失败或有异常出现则将错误信息输出到屏幕。

需要注意的是必须包含下列的处理方式:

  1. 启动三个进程,使用进程 1 读取员工工资数据,使用进程 2 计算个税及社保,使用进程 3 将数据写入到输出的工资单数据文件中。
  2. 三个进程负责不同的工作,进程之间使用某种机制进行通信。

目标

完成任务需要达成的目标:

  1. 程序存放的位置 /home/shiyanlou/calculator.py
  2. 程序必须采用多进程的方式处理员工工资数据,并保证进程间能够同步

提示语

下述实现方案仅供参考,会涉及到先前实验中学习到的知识点,如果自己对程序有足够的理解也可以不按照下述提示编写

  • 基于 multiprocessing 模块实现多进程
  • 基于 Queue 实现进程间通信
  • 实现完成后,可以考虑是否可以在计算环节的进程2实现为一个进程池?
  • 实现方案可以考虑定义 queue1queue2,实现三个进程如下:

    • 进程 1:从用户文件中读取数据,然后得到一个列表 data,第一项是用户 ID,第二项是税前工资,然后使用 queue1.put(data)
    • 进程 2queue1.get() 得到列表 data,第一项是用户 ID,第二项是税前工资,然后计算后生成新的列表。 newdata,包含社保,个税,税后工资等数据,然后使用 queue2.put(newdata)
    • 进程 3queue2.get() 得到列表 newdata,包含用户 ID,税前工资,社保,个税,税后工资等数据,然后写入文件。

最后,因为后续的挑战将会用到现在写的代码,请使用 下载代码 保存到本地或者提交到自己的 Github。

知识点

  • Python3 多进程
  • 进程间通信
  • 函数

通过代码如下:(注意,本代码并没有使用到Value进程同步以及加锁,还有进程池也没加进去)

#!/usr/bin/env python3
# _*_ coding: utf-8 _*_
import sys
import csv
import time
from multiprocessing import Process,Queue,Value,Lock,Pool

class Brgs:
    def __init__(self):   
        l = sys.argv[1:]
        self.c = l[l.index('-c')+1]
        self.d = l[l.index('-d')+1]
        self.o = l[l.index('-o')+1]

class Config:

    def __init__(self):
        self.config = self._read_config()

    def _read_config(self):
        d = {'s': 0}
        with open(brgs.c) as f1:
            for line in f1.readlines():
                m = line.split('=')
                a, b = m[0].strip(), m[1].strip()
                if a == 'JiShuL' or a == 'JiShuH':
                    d[a] = float(b)
                else:
                    d['s'] += float(b)
        return d

def f2(q2,q1):
    #pool = Pool(processes=3)
    for a,b in q1.get():   
        salary = int(b)
        shebao = salary * config['s']
        if salary < config['JiShuL']:
            shebao = config['JiShuL'] * config['s']
        if salary > config['JiShuH']:
            shebao = config['JiShuH'] * config["s"]
        m = salary - shebao - 3500
        if m <= 0:
            shui = 0
        elif m <= 1500:
            shui = m * 0.03
        elif m <= 4500:
            shui = m * 0.1-105
        elif m <= 9000:
            shui = m * 0.2-555
        elif m <= 35000:
            shui = m * 0.25-1005
        elif m <= 55000:
            shui = m * 0.3-2755
        elif m <= 80000:
            shui = m * 0.35-5505
        else:
            shui = m * 0.45-13505
        shuihou = salary - shebao - shui
        newdata1 = [a,salary, format(shebao, '.2f'), format(shui, '.2f'), format(shuihou, '.2f')]
        time.sleep(0.01)
        newdata.append(newdata1)
        #p=pool.apply(f5,(newdata1,))
        #pool.close()
        #pool.join()
    q2.put(newdata)

#def f5(n1):
    #newdata2 =newdata.append(n1)
    #return(newdata2)

def f1(q1):
    with open(brgs.d) as f:
        data = list(csv.reader(f))
    q1.put(data)

def f3(q2):
    with open(brgs.o, 'w') as f:
        for w in q2.get():      
            csv.writer(f).writerow(w)

def main():
    Process(target=f1, args=(queue1,)).start()
    Process(target=f2, args=(queue2, queue1)).start()
    Process(target=f3, args=(queue2,)).start()

if __name__ == '__main__':
   queue1 = Queue()
   queue2 = Queue()
   brgs = Brgs()
   config = Config().config
   newdata = []
   main()

 

posted @ 2018-05-21 11:10  时代的稻草人  阅读(1138)  评论(0编辑  收藏  举报