进程

1.进程的定义

  1. 进程是资源分配最小单位
  2. 当一个可执行程序被系统执行(分配内存等资源)就变成了一个进程
  1. 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,这种执行的程序就称之为进程
  2. 程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念
  3. 在多道编程中,我们允许多个程序同时加载到内存中,在操作系统的调度下,可以实现并发地执行。
  4. 进程的出现让每个用户感觉到自己独享CPU,因此,进程就是为了在CPU上实现多道编程而提出的。
  5. 进程之间有自己独立的内存,各进程之间不能相互访问
  6. 创建一个新线程很简单,创建新进程需要对父进程进行复制

多道编程概念

多道编程: 在计算机内存中同时存放几道相互独立的程序,他们共享系统资源,相互穿插运行
单道编程: 计算机内存中只允许一个的程序运行

2. 有了进程为什么还要线程?

总:进程不能共享资源,线程可以

  1. 进程优点:
    提供了多道编程,让我们感觉我们每个人都拥有自己的CPU和其他资源,可以提高计算机的利用率
  2. 进程的两个重要缺点
    a. 第一点:进程只能在一个时间干一件事,如果想同时干两件事或多件事,进程就无能为力了。
    b. 第二点:进程在执行的过程中如果阻塞,即使进程中有些工作不依赖于输入的数据,也将无法执行(例如等待输入,整个进程就会挂起)。
    c. 例如,我们在使用qq聊天, qq做为一个独立进程如果同一时间只能干一件事,那他如何实现在同一时刻 即能监听键盘输入、又能监听其它人给你发的消息
    d. 你会说,操作系统不是有分时么?分时是指在不同进程间的分时呀
    e. 即操作系统处理一会你的qq任务,又切换到word文档任务上了,每个cpu时间片分给你的qq程序时,你的qq还是只能同时干一件事呀

3. 进程间互相访问数据的四种方法

注:不同进程间内存是不共享的,所以互相之间不能访问对方数据

法1: 利用Queues实现父进程到子进程(或子进程间)的数据传递
法2: 使用管道pipe实现两个进程间数据传递
法3: Managers实现很多进程间数据共享
法4:借助redis中间件进行数据共享

4.进程池

from  multiprocessing import Process,Pool
import time,os
def foo(i):
    time.sleep(2)
    print("in the process",os.getpid()) 
    #打印子进程的pid
return i+100

def call(arg):
print('-->exec done:',arg,os.getpid())

if __name__ == '__main__':
    pool = Pool(3)                      
    #进程池最多允许5个进程放入进程池
    print("主进程pid:",os.getpid())     
    #打印父进程的pid
    for i in range(10):
       #用法1 callback作用是指定只有当Foo运行结束后就执行callback调用的函数,父进程调用的callback函数
        pool.apply_async(func=foo, args=(i,),callback=call)
        #用法2 串行 启动进程不在用Process而是直接用pool.apply()
        # pool.apply(func=foo, args=(i,))
    print('end')
    pool.close()    
    #关闭pool
    pool.join()     
    #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

5. 进程和程序的区别

  1. 程序只是一个普通文件,是一个机器代码指令和数据的集合,所以,程序是一个静态的实体
  2. 而进程是程序运行在数据集上的动态过程,进程是一个动态实体,它应创建而产生,应调度执行因等待资源或事件而被处于等待状态,因完成任务而被撤消
  3. 进程是系统进行资源分配和调度的一个独立单位
    4.一个程序对应多个进程,一个进程为多个程序服务(两者之间是多对多的关系)
  4. 一个程序执行在不同的数据集上就成为不同的进程,可以用进程控制块来唯一地标识每个进程

6.如何创建进程

shell—命令行解释器(shell相当于我们命令行的界面,如果我们从键盘中敲入一个指令时,shell就会执行这条指令)。

系统调用open返回的是一个文件描述符,类型为int,C库中的fopen返回的是文件流指针:FILE*。
我们所说的缓冲区(printf),用户态的一个缓冲区,是文件流指针自带的
printf, fwrite这些库函数都是先把数据写入到缓冲区中,等缓冲区写满了之后或者其他;条件满足之后才会写入到真正的文件中,而系统调用没有这个用户态的缓冲区(是直接将数据写入到文件中)这个说法不准确
fork() —(通过复制调用生成一个新的进程)创建一个子进程。
对于父进程来说,fork()的返回值是子进程的pid
对于子进程来说,fork()的返回值是0
因为子进程是根据父进程为模板来创建的,因此父子的代码段是一样的(父子进程运行的是同一段代码)。但是父子进程的返回值不同。父子进程的数据不相同。子进程的数据会另外开辟内存来存放。
对于代码来说父子进程是相同的(相同的代码只是fork()之下的代码,而不是从头到尾),但是父子进程的数据是独有的(写时复制技术)。
父进程是从代码头到代码的结束。子进程是从fork()开始到代码结束。
用户就是通过返回值来判断分辨父子进程,来进行代码的分流。
kill 进程号----》杀死进程。

7.进程的状态

    R(running)            运行态:并不意味着程序一定在运行中,它表明进程要么在运行中要么在运行队列里。
    S(sleeping)           可中断的休眠(浅度睡眠)
    D(disk sleep)         不可被中断的休眠,只能通过指定的方式--->唤醒(深度睡眠)
    T(stopped)            停止的状态
    t(tracing stop)       追踪状态
    X(dead)                 死亡状态
    Z(zombie)             僵死态

8.僵尸进程

产生原因:
子进程先于父进程退出,它会保存自己的退出状态,因此它不会自动释放所有资源。子进程退出后会通知父进程子进程退出了,然后让父进程去获取退出状态,然后完全释放子进程资源。假如父进程不管子进程的退出状态,那么这个子进程就会变成一个僵死进程。
僵尸进程的危害:资源泄露,正常的进程可能无法创建。
僵死进程如何杀死:杀死它的父进程就可以了。

下面是一个僵尸进程的演示:

import os,sys,time

pid = os.fork()
getpid = os.getpid()
getppid = os.getppid()

if pid == 0:
    print("this is child pid=%d,getpid=%d,getppid=%d" %(pid,getpid,getppid))
else:
    print ("This is parent pid=%d,getpid=%d,getppid=%d"%(pid,getpid,getppid))
    time.sleep(10)

当子进程还没有退出的时候:此时的子进程和父进程都没有退出。(使用ps aux查看进程的状态)

当子进程退出的时候:因为父进程还没有退出的时候,而子进程退出了,所以子进程就变成了一个僵尸进程。如下所示:(第一个是父进程,第二个是子进程(现在变成了僵尸进程))。

9.孤儿进程

产生的原因:
父进程先于子进程退出,那么这个子进程就会变成一个孤儿进程,并且进入后台运行。
特性:
它原来的父进程退出后。它的父进程就变成了init进程,如果子进程退出后,init进程将负责释放子进程的资源,所以子进程就不会变成一个僵死进程。
孤儿进程运行时,是后台运行,你可以继续输入其他的指令。

下面是孤儿进程的代码演示:

import os,sys,time

pid = os.fork()
getpid = os.getpid()
getppid = os.getppid()

if pid == 0:
    print("this is child pid=%d,getpid=%d,getppid=%d" %(pid,getpid,getppid))
else:
    print("This is parent pid=%d,getpid=%d,getppid=%d"%(pid,getpid,getppid))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值