mysql 第九节 多进程开发

=====day09.多进程开发==================


1.回顾:
Lock
队列分类 (先进先出,先进后出,优先级队列,双向队列)
生产者消费者 (用到队列和多线程)

 

2.什么是多进程?

1.概念:
一个程序运行起来后,代码+用到的资源 称之为进程,
它是操作系统分配资源的基本单元。

线程:是程序执行的最小单元,
是系统独立调度和分配CPU(独立运行)的基本单位。

进程:分配和管理资源的基本单位。一个进程包括多个线程。

多进程:同时执行的多个程序。

 

3.multiprocessing模块:

-- 1.Unix/Linux操作系统:(引言,引出multiprocessing)

-- Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。
-- 普通的函数调用,调用一次,返回一次,但是fork()调用一次,
-- 返回两次,因为操作系统自动把当前进程(称为父进程)复制了
-- 一份(称为子进程),然后,分别在父进程和子进程内返回。
-- 子进程永远返回0,而父进程返回子进程的ID。

-- import os

-- print('进程开始启动:', os.getpid())
-- pid = os.fork()
-- if pid == 0:
-- print('我是子进程:', os.getpid())
-- else:
-- print(pid)
-- print('我是父进程:', os.getpid())

2.Windows系统?

如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。
由于Windows没有fork调用,难道在Windows上无法用Python编写多
进程的程序?

由于Python是跨平台的,自然也应该提供一个跨平台的多进程
支持。multiprocessing模块就是跨平台版本的多进程模块。

 

4.初识多进程:

from multiprocessing import Process
import os


def son_pid():

print('子进程pid', os.getpid())


if __name__=='__main__':

p = Process(target=son_pid)
p.start()
p.join()

print('父进程pid', os.getpid())


5.进程的状态:
为了便于管理进程,经常依据进程在执行过程中的不同情况至少
定义三种不同的进程状态:

(1)运行(running)态:进程占有处理器正在运行。
(2)就绪(ready)态:进程运行条件已满足,等待cup执行。
(3)等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。

-- 在一个实际的系统里进程的状态及其转换比上面叙述的复杂一些,
-- 如,引入新建态(new)和死亡/终止态(exit )。

 


6. Process语法结构如下:

1. Process(target=,args=(,))

target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码
args:给target指定的函数传递的参数,以元组的方式传递


2.Process创建的实例对象的常用方法:

start():启动子进程实例(创建子进程)
join([timeout]):是否等待子进程执行结束,或等待多少秒。

is_alive():判断进程子进程是否还在活着。
terminate():不管任务是否完成,立即终止子进程。


3.Process创建的实例对象的常用属性:
name:当前进程的别名,默认为Process-N,N为从1开始递增的整数
pid:当前进程的pid(进程号)

 

7. 给子进程指定的函数传递参数:

from multiprocessing import Process
import os+
from time import sleep


def son_process(name, age, **kwargs):

for i in range(10):
print('子进程运行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))
print(kwargs)

sleep(0.2)

if __name__=='__main__':

p = Process(target=son_process, args=('test',18), kwargs={"m":20})
p.start()

sleep(1) # 1秒中之后,立即结束子进程
p.terminate()


===========================
===========================

 

8. 进程间不共享全局变量:(反例)

from multiprocessing import Process
from threading import Thread

nums = [11, 22]

def work1():

print('work1, 加入之前nums为:', nums)
for i in range(3):
nums.append(i)
# time.sleep(1)
print("在work1中,nums为", nums)


def work2():
print("在work2中,nums为:", nums)


if __name__ == '__main__':

p1 = Process(target=work1)
p2 = Process(target=work2)

p1.start()
p2.start()
p1.join()
p2.join()

# t1 = Thread(target=work1)
# t2 = Thread(target=work2)
#
# t1.start()
# t2.start()
# t1.join()
# t2.join()

 

9.使用进程池:
-- 如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,
-- 此时就可以用到multiprocessing模块提供的Pool方法。

from multiprocessing import Pool
import os
import time


def task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
time.sleep(1)


if __name__ == '__main__':

print('父进程pid为:', os.getpid())

p = Pool(4)

for i in range(10):
p.apply_async(task, args=(i,))

# close():关闭Pool,使其不再接受新的任务;
p.close()
# join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;
p.join()
print('所有任务都结束了')

 


10.进程间通信:
Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。
Python的multiprocessing模块包装了底层的机制,提供了Queue、管道Pipes
共享内存、 套接字socket、 信号。

from multiprocessing import Process, Queue, Pool
import os, time, random


# 写数据进程执行的代码:
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())


# 读数据进程执行的代码:
def read(q):
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)


if __name__=='__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()

pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))

# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr.start()

# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr.terminate()

 


===========管道的应用例子,创建一个管道,两个口都能收发
import multiprocessing
import os

def func(conn): #conn管道类型
conn.send(["a","b","c","d","e"]) #发送的数据
print("子进程",os.getpid(),conn.recv()) #收到的数据
conn.close() #关闭

if __name__=="__main__":
conn_a,conn_b=multiprocessing.Pipe() #创建一个管道,两个口
#print(id(conn_a),id(conn_b))
#print(type(conn_a), type(conn_b)) #multiprocessing.connection.PipeConnection类型
p=multiprocessing.Process(target=func,args=(conn_a,))
p.start()
conn_b.send([1,2,3,4,5,6,7])
print("主进程:",os.getpid(),conn_b.recv())
p.join()
===========================================


11.总结:
进程与线程区别
进程间通信
进程池

 

posted @ 2019-09-29 09:08  霸龙涛  阅读(51)  评论(0)    收藏  举报