25.进程和Process

进程介绍和Process

1、什么是进程
  • 一个程序运行起来后,它的代码以及需要使用到的资源,称之为进程,它是操作系统分配资源的基本单元,还是线程的容器,一个进程中会有一个或多个线程
  • 不仅是可以通过线程来完成多任务操作,进程也是可以的
2、进程的状态
  • 工作中,任务数往往会大于CPU的核数。那么肯定有一部分任务正在执行,而另外一部分任务在等待CPU的资源分配,因此就导致进程会有不同的状态
    a.就绪状态:运行的条件都已经满足,正在等待CPU的资源分配过来
    b.执行状态:CPU正在执行该进程
    c.等待状态:在等待某些条件满足。例如:一个程序正在sleep,此时就是等待状态
3、进程、线程进行对比
  • 功能
    a.进程:能够完成多任务;比如在一台电脑上能够同时运行多个软件
    b.线程:能够完成多任务;比如一个浏览器可以开多个窗口
  • 定义的不同
    a.进程:是操作系统进行资源分配和调度的基本单位
    b.线程:线程是进程的一个实体,是CPU进行调度和分派的基本单位。它是比进程更小的能独立运行的单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(比如程序计数器,一组寄存器和栈),但是它可以和同属一个进程之间的其它线程共享该进程所拥有的全部资源
  • 区别
    a.一个程序至少有一个进程,一个进程至少有一个线程
    b.线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高
    c.进程在执行过程中拥有独立的内存空间,而该进程的多个线程可以共享这个内存空间,从而极大提高了程序的运行效率
    d.不同进程之间的内存空间是独立的
    e.线程不能够独立运行,必须依赖于进程
  • 优缺点
    a.线程的执行开销小,但是不利于资源的管理和保护(线程之间资源共享)
    b.进程的执行开销大,但是有利于资源的管理和保护(进程之间资源不共享)
4、multiprocessing
  • 官方说明
    multiprocessing 是一个用与threading模块相似API的支持产生进程的包. multiprocessing包同时提供本地和远程并发,使用子进程代替线程,有效避免Global Interpreter Lock带来的影响。因此,multiprocessing模块允许程序员充分利用机器上的多个核心。Unix 和 Windows 上都可以运行。
  • Process类
    通过创建一个Process对象然后调用它的start()方法来生成进程。 Processthreading.Thread 的API相同。
  1. Process(group, target, name, args, kwargs)
    group:指定进程组,大部分情况使用不到
    target:如果传递了函数的引用,这个子进程就会执行这个函数
    name:给子进程设置名字,可不设置
    args:给target指定的函数传递参数,tuple
    kwargs:给target指定的函数传递参数,dict
  2. Process创建的实例对象的常用方法:
    start():启动子进程实例(创建子进程)
    is_alive():判断进程的子进程是否还存活
    join(timeout):是否等待子进程执行结束,或者等待指定的秒数,然后再进行下面的代码
    terminate():不管任务是否完成,立刻终止子进程
    3.Process创建的实例对象的常用属性:
    name:当前进程的别名,默认为Process-N,N是从1开始递增的整数
    pid:当前进程的pid(进程号),可以用os.getpid()查看
5、代码例子
  • 1、使用进程执行简单任务
import time
from multiprocessing import Process


def work1():
    print('喝水5秒')
    for i in range(5):
        time.sleep(1)
        print('喝水中...')


def work2():
    print('浇花4秒')
    for i in range(4):
        time.sleep(1)
        print('浇花中...')


""" 使用多进程来执行多任务"""

if __name__ == '__main__':  # Process在windows系统运行必须在__main__中,mac则不需要
    p1 = Process(target=work1)
    p2 = Process(target=work2)
    p1.start()
    p2.start() 
  • 2、Process执行的注意事项
    Process在windows系统运行必须在__main__块中,mac则不需要
    去掉__main__直接运行

    加入__main__进行运行

  • 3、创建带参的进程类
    方式和Thread一样,重写__init__run方法
from multiprocessing import Process


class MyPrecess(Process):

    def __init__(self, value):
        self.value = value
        super().__init__()

    def run(self):
        for i in range(10):
            print(F'进程{self.name}的{self.value}在跑第{i}次')  # 获取进程名


if __name__ == '__main__':
     p = []
     p1 = MyPrecess(value='lzl')
     p2 = MyPrecess(value='lzl')
     p.append(p1)
     p.append(p2)
     p1.start()
     p[0].terminate()  # 终止p1
     p2.start() 
  • 4、多进程操作全局变量
    1.进程各自拥有自己的变量,不会对全局变量有影响。比如1个主进程中有2个子进程,那么这三个进程都拥有自己的“全局变量”
    2.下面例子中,number会有三个值:0、500000、1000000
from multiprocessing import Process

number = 0


def work1():
    for i in range(0, 1000000):
        global number
        number += 1
    print(number)


def work2():
    for i in range(0, 500000):
        global number
        number += 1
    print(number)


if __name__ == '__main__':
    p1 = Process(target=work1)
    p2 = Process(target=work2)
    p1.start()
    p2.start()
    print(number)
    '''
    三个值:
    0
    500000
    1000000
    ''' 
  • 5、多进程操作系统资源
    1.文件是系统资源,进程之间会共用,并会有资源竞争
    2.下面的例子中,跑出来的结果中。文件中的内容并不是1000行java、1000行python
from multiprocessing import Process


def work1():
    for i in range(0, 1000):
        with open(r"D:\python\test_09\test\test.txt", 'a') as f:
            f.write('python\n')


def work2():
    for i in range(0, 1000):
        with open(r"D:\python\test_09\test\test.txt", 'a') as f:
            f.write('java\n')


if __name__ == '__main__':
    p1 = Process(target=work1)
    p2 = Process(target=work2)
    p1.start()
    p2.start()
    p1.join()
    p2.join() 

3.出现这个bug的原因,类似线程对共享资源的竞争,进程函数还在运行时,系统切换了进程资源,导致上一个进程的内容还没完全写入到文件中。

上面例子的结果:
不加锁的结果

  • 6、解决进程之间对系统资源的竞争关系
    1.使用锁,对进程进行串行处理。同一时刻只能有一个进程在执行
    2.因为是进程,所以锁对象只能通过参数来传递给进程所调用的函数或类
    3.使用锁来解决上面例子的bug
from multiprocessing import Process
from multiprocessing import Lock


def work1(lock):
    # 操作之前加锁
    lock.acquire()
    for i in range(0, 1000):
        with open(r"D:\python\test_09\test\test.txt", 'a') as f:
            f.write('python\n')
    # 操作结束后释放锁
    lock.release()


def work2(lock):
    lock.acquire()
    for i in range(0, 1000):
        with open(r"D:\python\test_09\test\test.txt", 'a') as f:
            f.write('java\n')
    lock.release()


if __name__ == '__main__':
    lock = Lock()
    p1 = Process(target=work1, args=(lock,))
    p2 = Process(target=work2, args=(lock,))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

结果:
加了锁的结果
6、进程之间的通信
  • 1、进程之间的通信使用的也是队列,不过并不是线程所使用的队列
    queue.Queue:进程内的线程之间的队列
    multiprocess.Queue:进程之间的队列

  • 2、multiprocess.Queue
    可以使用multiprocess.Queue来实现多进程之间的数据的传递,Queue本身是一个消息队列程序。
    注意:multiprocess.Queue需要把它的实例对象,以参数的形式传入到各个进程任务中(不会被复制到进程的内存中,只是传递过去),否则各个进程使用的还是各自的队列(也就是把队列复制到各自的内存里了),无法形成进程之间的数据传递

from multiprocessing import Process
from multiprocessing import Queue
import os

q = Queue()  # 创建队列
# 给队列添加数据
for i in range(5):
    q.put(i)

"""如果不使用传参的方式,那么两个进程之间使用的队列是各自的队列,不能完成通信"""


def work1(q):  # 使用同一个队列资源
    while not q.empty():
        print(F"进程{os.getpid()}在获取队列中的数据{q.get()}")


def work2(q):  # 使用同一个队列资源
    while not q.empty():
        print(F"进程{os.getpid()}在获取队列中的数据{q.get()}")


if __name__ == '__main__':
    p1 = Process(target=work1, args=(q,))
    p2 = Process(target=work2, args=(q,))
    p1.start()
    p2.start()
'''
结果:两个进程使用的是同个队列的资源,实现了进程之间的通信

进程8380在获取队列中的数据0
进程8380在获取队列中的数据1
进程8380在获取队列中的数据2
进程8380在获取队列中的数据3
进程8380在获取队列中的数据4
'''
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容

  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 5,950评论 3 28
  • 进程、进程的使用、进程注意点、进程间通信-Queue、进程池Pool、进程与线程对比、文件夹拷贝器-多任务 1.进...
    Cestine阅读 763评论 0 0
  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,525评论 0 5
  • 进程 操作系统背景知识 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。 进程的概念起源于操作...
    go以恒阅读 934评论 0 2
  • 账号申请 要开发iOS App,首先要有账号,账号分三种: 个人版 App Store 版 企业版 上面三种是通俗...
    勇往直前888阅读 1,295评论 0 1