Python中的进程

时间:2023-03-09 16:51:53
Python中的进程

进程

from multiprocessing import Process
import time def start(name):
time.sleep(1)
print('hello', name) if __name__ == '__main__':
# 开辟一个进程
p = Process(target=start, args=('zhangsan',))
# 再开辟一个进程
p1 = Process(target=start, args=('lisi',))
p.start()
p1.start()
p.join()

Python中的进程

进程间通讯,每个进程都有自己的内存空间,因此不同进程内存是不共享的,要想实现两个进程间的数据交换,有几种方法

Queue(队列)

def start(q):
q.put('hello') if __name__ == '__main__':
q = Queue()
p = Process(target=start, args=(q,))
p.start()
print(q.get())
p.join()

Python中的进程

Pipe(管道)

把管道的两头分别赋给两个进程,实现两个进程的互相通信

def start(left_conn):
right_conn.send('你好') # 发送
print(right_conn.recv()) # 接收
right_conn.close() if __name__ == '__main__':
left_conn, right_conn = Pipe() # 生成管道
p = Process(target=start, args=(right_conn,))
p.start()
print(left_conn.recv()) # 接收
left_conn.send('你也好') # 发送
p.join()

左管道发送,右管道接收,随后右管道返回消息,左管道接收,关闭管道

Python中的进程

Manager实现了进程间真正的通信共享


from multiprocessing import Process, Manager def f(dic, i):
dic[i] = i
if __name__ == '__main__':
manager = Manager()
dic = manager.dict() # 通过manager生成一个字典
p_list = []
for i in range(10):
p = Process(target=f, args=(dic, i))
p.start()
p_list.append(p)
# 等待所有进程执行完毕
for res in p_list:
res.join()
print(dic)

Python中的进程

进程池

进程池内部维护一个进程序列,当使用时,则去进程池获取一个进程,如果进程池序列中没有可以使用的进程,那么程序就会等待,直到进程池中有可用进程为止。

from multiprocessing import Process, Pool
import time def Foo(i): return i + 100 def Bar(arg):
print('number:', arg) if __name__ == '__main__':
pool = Pool(3) # 定义一个进程池,里面有3个进程
for i in range(10):
# callback是回调函数,就是在执行完Foo方法后会自动执行Bar函数,并且会把Foo函数的返回值作为参数传入Bar参数
pool.apply_async(func=Foo, args=(i,), callback=Bar)
# 必须先关闭进程池,在关闭进程池中的进程
pool.close()
# 等待进程池中的进程结束后关闭
pool.join()

程序会一次拿出来三个从池子里,直到没有

Python中的进程

from greenlet import greenlet
import time
def test1():
print('---aaa---')
time.sleep(1)
gr2.switch()
print('---bbb---')
time.sleep(1)
gr2.switch() def test2():
print('-----ccc-----')
time.sleep(1)
gr1.switch()
print('-----ddd-----')
while 1:
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

协程

微线程,协程能保留上次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。

协程有极高的执行效率,因为子程序切换不是线程切换,而是自身控制,因此,没有线程切换的开销。

不需要多线程的锁机制,因为它本身只有一个线程,只需要判断状态就好,所以效率高

因为协程是一个线程进行,所以想要利用多核CPU,就是多进程加协程

符合协程的条件:

  1. 必须在只有一个单线程里并发
  2. 修改共享数据不需要加锁
  3. 用户程序里自己保存多个控制流的上下文
  4. 一个协程遇到IO操作自动切换到其他协程

python的两个协程模块:

  • greenlet(执行顺序需要手动控制)
from greenlet import greenlet
import time
def test1():
print('---aaa---')
time.sleep(1)
gr2.switch()
print('---bbb---')
time.sleep(1)
gr2.switch() def test2():
print('-----ccc-----')
time.sleep(1)
gr1.switch()
print('-----ddd-----')
while 1:
gr1 = greenlet(test1)
gr2 = greenlet(test2)
print('开始启动')
gr1.switch()

手动切换协程,当运行到aaa,切换到ccc,再次切换回去,并且会记录上一次执行完aaa的位置,会从bbb开始执行,如此循环下去,就会出现如下图所示的结果

Python中的进程