python基础 进程、操作系统调度算法、同步异步、开启进程、process类的参数、进程锁、ipc机制

发布时间 2023-07-05 16:18:17作者: 初学程序员

进程概念

  进程、线程都是操作系统中的基本概念,也就是说进程和线程都是操作系统层的东西,专业术语表达就是进程和线程的使用都是由操作系统来调度的‘,而不是由我们来操控的。

  在操作系统这门课里,进程和线程是操作系统的概念,协程不是操作系统中的概念,而是我们程序层面的

  协层使我们程序员自己来调用的,不是由操作系统来调用的,也就是说,在操作系统中没有协程的概念

进程是用来干什么的:

  进程可以用来做任务,比如:听歌、看视频等

什么是进程  

  eg:
    厨师做饭,厨师按照菜谱来做菜,那么,菜谱就是程序,而做饭的过程就是进程,在这个过程中,厨师就是线程,所以,厨师才是真正做事的,言外之意线程才是真正干活的,而进程不是,进程只是一个过程

进程和程序的区别

  1.程序就是一堆死的东西,没有生命周期

  2.进程是有生命周期的,当一个任务进行完毕之后,进程就不存在了

进程中是要有线程的,进程中如果没有线程是没有意义的,一个进程中是可以有多个线程的,一个进程中至少要有一个线程

进程和线程都是有操作系统来调度的
进程是操作系统的一个独立的单位

’补充:CPU的工作机制 

  1. 当CPU遇到I/O操作的时候,会剥夺CPU的执行权限
  2. 当遇到的任务需要占用大量的时间的时候,也会剥夺执行权限

其实CPU的工作机制就是来回切换做到的

I/O密集型

  遇到阻塞,但是不需要占用大量的CPU资源,需要等待

计算密集型

  没有遇到阻塞,但是需要占用大量的CPU资源,也不需要等待

操作系统的调度算法(了解)

  1. 先来先服务调度算法
  2. 短作业优先调度算法
  3. 时间片轮转法
  4. 多级反馈队列
操作系统会自行选择哪一种算法

进程的并发和并行

并行:在‘同一时刻’,同时执行任务

CPU是多核的,单核的

单核的CPU做不到并行(在同一时刻要想执行多个任务,必须要求CPU有多个处理器(核))

并发:在一段时间内,看起来是同时执行任务,事实上,不是同一时刻

同步异步阻塞非阻塞

1.同步与异步

同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)
所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。
换句话说,就是由*调用者*主动等待这个*调用*的结果。

而异步则是相反,*调用*在发出之后,这个调用就直接返回了,所以没有返回结果。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。

举个通俗的例子:
你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

2. 阻塞与非阻塞

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.

阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

还是上面的例子,
你打电话问书店老板有没有《分布式系统》这本书,你如果是阻塞式调用,你会一直把自己“挂起”,直到得到这本书有没有的结果,如果是非阻塞式调用,你不管老板有没有告诉你,你自己先一边去玩了, 当然你也要偶尔过几分钟check一下老板有没有返回结果。
在这里阻塞与非阻塞与是否同步异步无关。跟老板通过什么方式回答你结果无关。

如何开启进程

使用的是内置的模块:multiprocess

from multiprocessing import Process
def task():
    with open('a.txt', 'w', encoding="utf8") as f:
        f.write('helloworld')
# 开一个进程来执行task这个任务
# 如何开进程
"""在Windows系统中,开启进程必须写在__main__中, 在其他系统中不用加"""
if __name__ == '__main__':
    p = Process(target=task)  # 得到一个对象,还没有开启进程呢,知识实例化了一个进程对象
    p.start()  # 调用这个方法才是真正的开启进程

Process类的参数

def task(name, name1, age, gender):
    print(name)
    print(name1)
    print("age:", age)
    print("gender:", gender)
 

if __name__ == '__main__':
    p = Process(target=task)  # 得到一个对象,还没有开启进程呢,知识实例化了一个进程对象
    """这个开启进程只是通知操作系统去开进程,因为开启进程需要时间的,所以,在一瞬间进程并没有开起来,然后代码往下执行了"""
     开启的这个进程叫子进程
    p = Process(target=task, name='ly_1', args=('kevin', 'jason'), kwargs={'age':18, 'gender':'male'})  # 得到一个对象,还没有开启进程呢,知识实例化了一个进程对象
    # 守护进程的作用:主进程结束,子进程也结束
    # 注意:p.daemon = True 必须要写在
    p.daemon = True  # 把p进程设置为守护进程p.start()之前
    p.start()  # 调用这个方法才是真正的开启进程

    # 如何查看一个进程的名字
    # Process-1, ly_1
    # print(p.name)  # 看的是p进程的名字
    print("123")
    """现在的现象是:主进程代码先执行,然后执行子进程里的代码,并且主进程代码执行完毕之后,子进程的代码并没有结束"""
参数含义:
  group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None
  每一个进程都有:进程名,进程id等属性 name: 代表的是进程的名字 args=(), 传参数的 kwargs={}传参的, daemon:守护进程 

方法介绍

p.terminate()  # 杀死进程
# True
 import time
time.sleep(1)
 # False
print(p.is_alive())  # 查看p进程是否存活
# join
# 现在让你先执行子进程中的代码,在执行主进程中的代码?
p.join()  # 先等待子进程执行完毕,在执行主进程

如何开启多进程

import time
def task(i):
    print("task:", i)
    time.sleep(1)

from multiprocessing import Process

if __name__ == '__main__':
    start_time = time.time()

    ll = []
    for i in range(5):
        # 开启多进程之后,有可能是没有顺序的
        p = Process(target=task, args=(i, ))
        p.start()
        # p.join()  # 5个进程变成了串行
        ll.append(p)

    for j in ll:
        j.join()
    """想让所有的子进程先执行完,在执行主进程"""
    print(123)
    print("time:", time.time() - start_time)

进程锁

锁:以后你遇到的所有关于加锁的都是为了保证数据的安全
MySQL中:行锁、表锁、悲观锁、乐观锁、等
进程锁、互斥锁、GIL锁、死锁等
def task(i, lock):
    # 上一把锁
    lock.acquire()
    print("第%s个进程进来了" % i)
    print("第%s个进程走了" % i)
    # 释放锁
    lock.release()


from multiprocessing import Process
from multiprocessing import Lock
if __name__ == '__main__':
    lock = Lock()
    for i in range(5):
        p = Process(target=task, args=(i, lock))
        p.start()

进程间的通信(IPC机制)

   进程是可以开启多个的,进程与进程之间是相互独立的,互不影响,进程是操作系统的一个独立单元
一个进程崩溃了,其他的进程不收影响

  在一个进程中不能修改另外一个进程的数据,言外之意是进程之间的数据是隔离的,互不影响

   要想在一个进程中使用另外一个进程中的数据,需要让进程之间通信(IPC