进程

发布时间 2023-07-05 19:06:49作者: Maverick-Lucky

进程

进程、线程的使用都是由操作系统来调度的,而不是由程序员来操控的。

进程的定义:

  进程就是一个正在运行的程序,是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。

进程和程序的区别:

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

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

进程只是一个过程,而线程才是真正去做任务的

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

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

补充:cpu工作机制(其实CPU的工作机制是来回切换做到的)

  1. 当cpu遇到I/O操作时,会剥夺CPU的执行权限

  2. 当遇到的任务需要占用大量的时间的时候,也会剥夺执行权限。

  I/O密集型:(input、output)

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

  计算密集型:

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

操作系统的调度算法(了解,操作系统会自行选择哪一种算法)

  1. 先来先服务调度算法

  2,短作业优先调度算法

  3. 时间片轮转法

  4. 多级反馈队列

进程的并发和并行

并行:

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

单核的CPU不能做到并行。

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

并行:

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

 同步异步阻塞非阻塞

 

同步异步

同步异步关注的是消息通信机制

同步依赖于上一次的结果

异步不依赖于上一次的结果

异步的效率比同步的效率高

 

阻塞与非阻塞

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

阻塞:调用结果返回之前,当前线程会被挂起。只有得到结果之后才会返回

非阻塞:在不能立刻得到结果之前,该调用不会阻塞当前线程。

 

开启进程

  使用的是内置模块:multiprocess

""在Windows系统中,开启进程必须写在__main__中,在其他系统中不用加""

from multiprocessing import Process

def task():
    print('helloworld')

if __name__ == '__main__':
    # 先实例化得到一个进程对象p
    p = Process(target=task)
    # 开启进程
    p.start()

 Process类的参数

  参数介绍:

  group参数未使用,值始终为None

  target表示调用对象,即子进程要执行的任务

  args表示调用对象的的位置参数元组

  kwargs表示调用对象的字典

  name为子进程的名字

  先执行主进程,在执行子进程

    """这个开启进程只是通知操作系统去开进程,因为开启进程需要时间的,所以,在一瞬间进程并没有开起来,然后代码往下执行了"""

from multiprocessing import Process

def task(name,name1,age,gender):
    print('helloworld')
    print(name)     # feifei
    print(name1)   # jolly
    print('age:', age)  # age: 4
    print('gender:', gender)    # gender: male
if __name__ == '__main__':
    # 先实例化得到一个进程对象p,并进行传参
    p = Process(target=task,name='hua',args=('feifei','jolly'),kwargs={'age':4,'gender':'male'})
    # 开启进程
    p.start() 
  print(p.name) # 打印进程的名字 hua

 """现在的现象是:主进程代码先执行,然后执行子进程里的代码,并且主进程代码执行完毕之后,子进程的代码并没有结束"""

结果:

 

daemon表示守护进程,作用:主进程结束,子进程也结束,要想使用守护进程,必须写在start之前。

from multiprocessing import Process
def
task(name,name1,age,gender): print('helloworld') print(name) # feifei print(name1) # jolly print('age:', age) # age: 4 print('gender:', gender) # gender: male if __name__ == '__main__': # 先实例化得到一个进程对象p,并进行传参
  # 开启的这个进程叫子进程
   p = Process(target=task,name='hua',args=('feifei','jolly'),kwargs={'age':4,'gender':'male'}) # 守护进程:主进程结束后,子进程也结束 p.daemon = True # 守护进程 # 开启进程 p.start()
  
print(p.name) # 查看进程的名字 hua

结果如图所示:

 

方法介绍

from multiprocessing import Process

def task(name,name1,age,gender):
    print('helloworld')
    print(name)     # feifei
    print(name1)   # jolly
    print('age:', age)  # age: 4
    print('gender:', gender)    # gender: male
if __name__ == '__main__':
    # 先实例化得到一个进程对象p,并进行传参
    p = Process(target=task,name='hua',args=('feifei','jolly'),kwargs={'age':4,'gender':'male'})

    # 守护进程:主进程结束后,子进程也结束
    # p.daemon = True # 守护进程
    # 开启进程
    p.start()
    # 强制执行
    p.terminate()
    # 查看p进程是否运行
    print(p.is_alive())  # 此时返回True ,因为操作系执行需要一段时间
    print(p.name)  # 打印进程的名字 hua

p.terminate() : 强制结束子进程

p.is_alive() : 判断进程是否结束,返回结果为布尔值

from multiprocessing import Process

def task(name,name1,age,gender):
    print('helloworld')
    print(name)     # feifei
    print(name1)   # jolly
    print('age:', age)  # age: 4
    print('gender:', gender)    # gender: male
if __name__ == '__main__':
    # 先实例化得到一个进程对象p,并进行传参
    p = Process(target=task,name='hua',args=('feifei','jolly'),kwargs={'age':4,'gender':'male'})

    # 守护进程:主进程结束后,子进程也结束
    # p.daemon = True # 守护进程
    # 开启进程
    p.start()
    # 杀死进程
    p.terminate()
    import time
    time.sleep(1)
    # 查看p进程是否运行
    print(p.is_alive())  # 此时返回False

    print(p.name)  # 打印进程的名字 hua

p.join() : 等子进程执行完毕,在执行主进程

from multiprocessing import Process

def task(name,name1,age,gender):
    print('helloworld')
    print(name)     # feifei
    print(name1)   # jolly
    print('age:', age)  # age: 4
    print('gender:', gender)    # gender: male
if __name__ == '__main__':
    # 先实例化得到一个进程对象p,并进行传参
    p = Process(target=task,name='hua',args=('feifei','jolly'),kwargs={'age':4,'gender':'male'})
    # 开启进程
    p.start()
    # 先执行子程序,再执行主程序
    p.join()
    print(p.name)  # 打印进程的名字 hua

结果:

开启多进程

利用for循环来完成多个字进程的运行

from multiprocessing import Process
def task(i):
    print("task:", i)
if __name__ == '__main__':
        for i in range(5):
        # 开启多进程之后,有可能是没有顺序的
        p = Process(target=task, args=(i, ))
        p.start()
        print(123)

结果:

  先执行所有的子程序在执行主程序

from multiprocessing import Process
def task(i):
    print("task:", i)

if __name__ == '__main__':

    ll = []
    for i in range(5):
        # 开启多进程之后,有可能是没有顺序的
        p = Process(target=task, args=(i, ))
        p.start()
        ll.append(p) # 将所得到的进程对象加在列表中

    for j in ll: # for循环取值,取出一个个子进程对象
        j.join()
    """想让所有的子进程先执行完,在执行主进程"""
    print(123)

进程锁

锁:加锁是为了保证数据的安全。

在MySQL中:行锁、表锁、悲观锁、乐观锁、等

在python中:进程锁、互斥锁、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()
    print(123)

结果:

 进程间的通信(IPC机制)

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

n =100
def task(name,name1,age,gender):
    global n
    n = 1

from multiprocessing import Process

if __name__ == '__main__':
    # 先实例化得到一个进程对象p
    p = Process(target=task)

结果:

 从上面可以看出:

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

要想在一个进程中使用另外一个进程中的数据,需要让进程之间通信,也就是IPC机制