进程基础

进程

1.程序与进程的区别

程序:一堆代码

进程:一堆代码的运行过程

2.进程调度

当代操作系统调度:

​ 时间片轮转法+分级反馈队列

  1. 先来先服务调度

    a,b程序,若a程序先来,先占用CPU。

    缺点:程序a先使用,程序b必须等待程序a使用CPU结束后才能使用。

  2. 短作业优先调度:

    a,b程序,谁的用时短,先优先调度使用CPU。

    缺点:若程序a使用时间长,有N个程序使用时间短,必须等待所有用时短的程序结束后才能使用。

  3. 时间片轮转法

    CPU执行的时间1秒中,加载N个程序,要将1秒等分成多个N个时间片。

  4. 分级反馈队列

    将执行优先分为多层级别。

    • 1级:优先级最高
    • 2级:优先级第二
    • 3级:优先级第三。。。以此类推

3.进程的三个状态

  1. 就绪态:

    所有进程创建时都会进入就绪态,准备调度。

  2. 运行态:

    调度后的进程,进入运行态

  3. 阻塞态:

    凡是遇到IO操作的进程,都会进入阻塞态。

    若IO结束,必须重新进入就绪态。

    ​

4.同步和异步

指的是提交任务的方式

4.1 同步

若有两个任务需要提交,在提交第一个任务时,必须等待该任务执行结束后,才能继续提交并执行第二个任务。

4.2 异步

若有两个任务需要提交,在提交第一个任务时,不需原地等待,立即可以提交并执行第二个任务。

5.阻塞与非阻塞

5.1 阻塞

阻塞态。遇到IO一定会阻塞。

5.2 非阻塞

非阻塞态。即就绪态和运行态

6.进程号回收的两种方式

  1. join方法(from multiprocessing import Process),可以回收子进程与主进程。
  2. 主进程正常结束,子进程与主进程也会被回收。

7.创建进程的两种方法

方法一:

导入Process类,直接实例化创建进程。

from multiprocessing import Process
import time

def task(name):
    print(f"{name}函数开始执行。。。")
    time.sleep(0.5)
    print(f'{name}函数执行结束。')

if __name__ == '__main__':
    p = Process(target=task,args=('task',))  # args要传元组
    p.start()
    print('主进程结束')

方法二:

导入Process类,继承此类创建新类。

类内部需要创建run方法,该方法则为进程需要完成的任务函数。

实例化新类,通过新类对象.start()开启进程。

from multiprocessing import Process
import time

class SomeProcess(Process):
    def run(self):
        print(f"{self.name}函数开始执行。。。")
        time.sleep(0.5)
        print(f'{self.name}函数执行结束。')

if __name__ == '__main__':
    p = SomeProcess()
    p.start()
    # p.join()
    print('主进程结束')

8.僵尸进程与孤儿进程(了解)

8.1 僵尸进程

指的是子进程已经结束了,但PID号还在,未销毁。

缺点:占用PID号,占用操作系统资源。

8.2 孤儿进程

指的是子进程还在执行,但父进程意外结束了。

操作系统优化机制:提供一个福利院,帮你回收没有父进程的子进程。

9.守护进程

指的是主进程结束后,该主进程产生的所有子进程跟着结束,并回收。

10.进程互斥锁

加锁可以保证

让并发变成串行,牺牲了执行效率(速度),保证了数据安全。

在程序并发执行时,需要修改数据时使用。

缺点:

  1. 效率低
  2. 需要自己加锁处理

11.队列

1.什么是队列

队列一种用来储存数据的容器,它的特性是:先进先出。可以用来实现多进程之间的数据传递。

相当于内存中产生一个队列空间,可以存放多个数据,但是数据的顺序是由先进去的排在前面。

优点:

  1. 效率高
  2. 帮我们处理好锁的问题

2.如何使用队列

from multiprocessing import Queue

# 调用Queue类,实例化出一个对象q
q = Queue(5)  # 5代表可以存放5个数据,如果没写,则可以存放无限大的数据

# 把数字1添加到队列当中
q.put(1)

# 添加数据,如果队列满了,就会报错
q.put_nowait(2)

# 判断队列中是否已满
print(q.full())

# 取出队列中的数据,若队列中没有数据,则会进入IO等待
print(q.get())

# 取出数据,若队列中没有则会报错
print(q.get_nowait())

# 判断队列是否为空
print(q.empty())


'''
False
1
2
True
'''

12.IPC(进程间通信)

进程间数据是相互隔离的,若想实现进程间通信,可以利用队列。

from multiprocessing import Process
from multiprocessing import Queue


def test1(q):
    data = '数据hello'
    q.put(data)
    print('进程1开始添加数据到队列中..')


def test2(q):
    data = q.get()

    print(f'进程2从队列中获取数据{data}')


if __name__ == '__main__':
    q = Queue()

    p1 = Process(target=test1, args=(q, ))
    p2 = Process(target=test2, args=(q, ))

    p1.start()
    p2.start()

    print('主')

    
'''
主
进程1开始添加数据到队列中..
进程2从队列中获取数据数据hello
'''    
posted @ 2019-10-21 19:40  Donner  阅读(136)  评论(0)    收藏  举报