进程:是计算机中最小的资源分配单位
进程的三状态:就绪 运行 阻塞
同步异步:
  同步:一件事情与另一件事情有一定的顺序
  异步:两件事情可以同时进行
并行和并发
  并行:在一个时间点上,有多个进程在被cpu计算
  并发:在一个时间段上,有多个进程在被cpu计算
阻塞和非阻塞
  阻塞:input sleep recv accept recvfrom
 非阻塞:不需要等待就可以直接完成的事情


进程
如何在Python代码中启动一个进程(实现异步)
这里要用到 multiprocessing 模块
进程模块:启动进程、基础的进程信息的获取、管理
进程的同步
进程之间的数据共享
进程之间的通信
进程池

# multiprocessing 跟进程相关的基本都在这个模块里

import time

def func():
    time.sleep(1)
    print(666)

func()
time.sleep(1)
print(777)



from multiprocessing import Process
import time

def func():
    time.sleep(1)
    print(666)

if __name__ == "__main__":
    Process(target=func).start()
    # 开启了一个新的进程,在这个新的进程里执行的 func()
    time.sleep(1)
    print(777)  # 主进程

# 777
# 666
# 运行结果仔细观察发现有异步的效果

 

import time
import os
from multiprocessing import Process

def func():
    time.sleep(1)
    print(666, os.getpid(), os.getppid())

if __name__ == "__main__":
    p = Process(target=func)  # 这里并不代表开启了子进程
    p.start()  # 开启了一个子进程,并执行func()
    time.sleep(1)
    print(777, os.getpid(), os.getppid())

# 777 12340 1636  # 主进程运行的结果
# 666 7604 12340  # 子进程运行的结果

# 由上面两行结果可以得出:
# 利用os.getpid()证明两个进程不一样
# 另外每次运行,os.getpid()结果都不一样
# 但是,12340是主进程的id,7604是子进程的id,1636是Pycharm的id,排列特点不变


# 几个概念:
#   父进程与子进程——
#       比如运行本文件,就是父进程
#       运行Process(target=func).start()就是子进程

#   主进程——一般直接执行的那个程序就是主进程

# 为什么要有 if __name__ == "__main__"
#    windows操作系统开启子进程的方式问题

 

# 如何开启多个子进程

import time
import os
from multiprocessing import Process

def func():
    time.sleep(3)
    print(666, os.getpid(), os.getppid())

if __name__ == "__main__":
    for i in range(10):
        p = Process(target=func)
        p.start()  #
    time.sleep(1)
    print(777, os.getpid(), os.getppid())

# 这里需要注意一点:Python程序一直都是逐行执行
# 但是因为这里设置了时间延迟,因此会先执行主程序的代码

# 777 6232 8396
# 666 13220 6232
# 666 14076 6232
# 666 9720 6232
# 666 12036 6232
# 666 1080 6232
# 666 3428 6232
# 666 1768 6232
# 666 11816 6232
# 666 2552 6232
# 666 13124 6232

# 观察结果发现主进程只运行了一次
# 然后剩下的全是一个子进程重新运行的结果
# 主进程运行完不会结束,它会等子进程全部运行结束
# 注意变量p拿到的是最后一个子进程的id

 

# 如何开启多个不同的子进程
# 这里也一样,程序是逐行解释,逐行执行

import time
import os
from multiprocessing import Process

def func():
    time.sleep(2)
    print(666, os.getpid(), os.getppid())

def func2():
    print(111)

if __name__ == "__main__":
    for i in range(3):
        p = Process(target=func)
        p.start()
    for i in range(2):
        p = Process(target=func2)
        p.start()
    time.sleep(1)
    print(777, os.getpid(), os.getppid())

# 111
# 111
# 777 3784 8396
# 666 4776 3784
# 666 10724 3784
# 666 12692 3784

 

# 如何给子进程传参数

from multiprocessing import Process

def func(name):
    print(666, name)

if __name__ == "__main__":
    p = Process(target=func,args=(777,))  # 注意是一个元组
    p.start()


import time
from multiprocessing import Process

def func(num, name):
    time.sleep(1)
    print(num, "hello", name)

if __name__ == "__main__":
    for i in range(10):
        p = Process(target=func, args=(i, "abc"))
        p.start()
    print("主进程")

# 主进程
# 0 hello abc
# 1 hello abc
# 3 hello abc
# 4 hello abc
# 2 hello abc
# 6 hello abc
# 7 hello abc
# 5 hello abc
# 8 hello abc
# 9 hello abc
# 注意子进程并不是完全按顺序运行的

# 子进程可以有返回值吗?
#   不能有返回值
#   因为子进程函数中的返回值无法传递给父进程


import time
from multiprocessing import Process

def wahaha():
    time.sleep(3)
    print("这是子进程,3s后才运行")

if __name__ == "__main__":
    Process(target=wahaha).start()
    print("主进程")

# 主进程
# 这是子进程,3s后才运行

# 主进程会默认等待子进程结束之后才结束
# 因为父进程要负责回收子进程占用的操作系统资源