python 进程的使用和理解

概述

一说进程,很多人就想要问线程,那么就先说下两者的不同吧

其实进程就是一个个的程序
那线程其实是进程里面的一个个子功能

在举例子来说明,我们以前在电脑前挂QQ,多个qq其实就是一个不同的进程,进程之间是相互独立运行的,也就是每一个进程都会消耗一份系统的资源。
那么线程呢,就比如说我们点开qq了,看到里面的各个功能,有什么聊天,小程序,发空间等等这些,他们就相当于一个个线程,也就是说,其实,进程里面是包含着线程的,并且,线程是的资源是共享的。

常用方法

我在工作过程中,主要使用的是进程,那能避免使用线程,我还是避免使用的,因为资源的共享,会导致出现很多的问题。

那接下来,我就直接说一下进程的简单使用吧:
首先在python中使用的库

from multiprocessing import Process,Manager,pool,Value

一般我是这么导入,和用到如下的库。

那么现在浅显的说一下上面的几个函数的使用方法吧

首先Process,就是启动一个进程,

p = process(参数)
p.start()

其次,Manager,Value的话,主要是多个进程如果使用同一个局部变量的话,就需要使用上面这两个函数
Manager有很多的方法,我主要使用dict和list两种,当然,如果dicct的话,会有一个坑,就是深层复制,无法复制成功,需要由外层进行引导。

最后pool的话是开始一个进程池,这个的话,其实使用方法大致和Process类似。

python multiprocessing

说明几点:

  • 首先,在进程里面是可以在接着开进程的。
    其实进程和线程可以搭配着使用,但是这样就会比较乱。
  • 资源共享需要事先声明,然后不管你开多少个进程,都是共享的,但是,千万不要再进程里面再去申明进程。
  • 资源共享Manager.dict()是有坑在里面的,现在接下来就说明这个问题

如果需要对dict的深层赋值,我们只能曾浅层开始一步步传值。
当时这片文章的一个理解,对我帮助特别大:
https://segmentfault.com/a/1190000018619281

我自己也写了如下代码,浅层次,从使用的角度,验证了一下:


from multiprocessing import Process,Manager

import datetime

class TestMul(object):

    def __init__(self):
        self.balck = Manager().dict()
        self.freeze = Manager().dict()
        self.ips = [
            "192.168.111.7",
            "192.168.111.8",
            "192.168.112.1",
            "192.168.112.2",
        ]


    def forall_sleep(fn):
        def inloop(self,*args):
            for ip in self.ips:
                print ip
                fn(self,ip,*args)
        return inloop


    def chose_dict(self):
        pass


    def decision(self,probelm):
        type_anmorl = {
            "fullblack": self.balck,
            "halfblack": self.freeze,
        }
        return type_anmorl[probelm]

    @forall_sleep
    def ip_write1(self,ip,problem):
        problem_dict,problem_type = self.decision(problem)
        if not problem_dict.has_key(ip):
            self.writ_dict2(problem_dict,ip)
            print problem_dict

        else:
            problem_dict["test"]["time"] +=1
            print problem_dict

        return problem_dict


# 问题的举例
    def writ_dict1(self,dict_massage,ip):
        dict_massage[ip] = str(datetime.datetime.now())
        dict_massage["test"] = {}
        row = dict_massage["test"]
        row["time"] = 1
        dict_massage["test"] = row
        dict_massage["a"] = {}
        dict_massage["a"]["b"] = str(datetime.datetime.now())
        print dict_massage

    def writ_dict2(self,dict_massage,ip):
        dict_massage[ip] = str(datetime.datetime.now())
        dict_massage["test"] = {}
        row = dict_massage["test"]
        row["time"] = 1
        dict_massage["test"] = row
        dict_massage["a"] = {}
        raw = dict_massage["a"]
        raw["b"] = str(datetime.datetime.now())
        dict_massage["a"] = raw
        print dict_massage




if __name__ == '__main__':
    t = TestMul()
    a = t.decision(probelm = "fullblack")
    # print a
    # t.ip_write1("fullblack")  #这个是一般装饰器的用法
    t.writ_dict1(a,"192.168.112.2")
    t.writ_dict2(a, "192.168.112.2")

结果如下:

{'test': {'time': 1}, 'a': {}, '192.168.112.2': '2021-01-01 17:18:49.486341'}
{'test': {'time': 1}, 'a': {'b': '2021-01-01 17:18:49.487344'}, '192.168.112.2': '2021-01-01 17:18:49.487202'}

直接看Manager生成的不同的代码就可以。

我当时还写了一个装饰器,那这里就额外对装饰的使用进行一个初步的说明吧。
装饰器其实就是简化了我们的一个使用,我上面写的装饰器,其实不太正规,但是,可以用来加深对装饰器的一个理解。
别人的文章会对装饰器多一个深度的剖析,但是,我们工作中,根本用不到那些东西。只需要把用到的掌握好就可以。

其实装饰主要是传参数和不传参数的,我们主要看最里面的那层嵌套就好了

    def forall_sleep(fn):
        def inloop(self,*args):
            for ip in self.ips:
                print ip
                fn(self,ip,*args)
        return inloop

首先,说一下*args一般情况呢,我们还可以带一个**kwargs这里我没带,但我都说一下,一个传入的是不定长的参数,一个字典型的参数,这两个呢,其实是对应你原函数的一个参数的。
接下来,要关注的是
fn(self,ip,*args)
t.ip_write1("fullblack")
fn其实是代表,原函数的,后面是他要调用的参数,这个是要跟原函数一一对应的。
能知道,我为什么就传入一个参数了吗?原函数可以两个呢?
这也是我为什么说,我写的这个装饰器不正规的原因。因为他不通用。

@forall_sleep
    def ip_write1(self,ip,problem):
        problem_dict,problem_type = self.decision(problem)
        if not problem_dict.has_key(ip):
            self.writ_dict2(problem_dict,ip)
            print problem_dict

因为这个ip,我放在装饰器中去了。
关于使用装饰器,函数是怎么调用的,我推荐大家看我的另一篇文章,当然,也不是我的自卖自夸。
https://blog.csdn.net/weixin_43635231/article/details/110442738

接着说,上面,进程dict的解决办法,其实就是改成这么调用就可以了

#例子:
def test(idx, test_dict):
    test_dict['test'][idx] = idx

## 正确的使用方式

def test(idx, test_dict):
    row = test_dict['test']
    row[idx] = idx
    test_dict['test'] = row

确实有点麻烦,但是却又是无可奈何

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值