进程的概念

程序:例如xxx.py这是程序,是一个静态的

 

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

 

不仅可以通过线程完成多任务,进程也是可以的

 

 

进程的状态:

工作中,任务数往往大于cpu的核数,即一定有一些任务正在执行,而另一些任务在等待cup进行执行,因此导致了有了不同的状态

 

 

就绪态:运行的条件都已经慢去,正在等在cpu执行

执行态:cpu正在执行其功能

等待态:等待某些条件满足,例如一个程序sleep了,此时就处于等待态

 

 

进程、线程对比

(1、一个程序至少有一个进程,一个进程至少有一个线程

(2、线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发行高

(3、进程在执行过程中拥有独立的内存单元,而多个线程共享进(进程所分配的资源)内存,从而极大地提高了程序的运行效率

 

 

创建进程-multiprocessing模块

1、 由于python是跨平台的,自然应该提供一个跨平台的多进程支持。Multiprocessing模块就是跨平台版本的多进程模块

2、 Multiprocessing模块提供了一个Process类来表示一个进程对象,创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,join()方法可以等待子进程结束后在继续往下运行,通常用于进程间的同步

 

Process语法结构

Process([group[,target[,name[,args[,kwargs]]]]])

target:如果传递了函数的引用,可以任务这个子进程就执行这里的代码

args:给target指定的函数传递的参数,以数组的方式传递

kwargs:给target指定的函数传递命名函数

name:给进程设定一个名字,可以不设定

group:指定进程组,大多数情况下用不到

 

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

start():启动子进程实例(创建子进程)

is_alive():判断主进程子进程是否还在活着

join([timeout]):是否等待子进程执行结束,或等待多少秒

terminate():不管任务是否完成,立即终止子进程

 

Process创建的实例对象的常用属性:

name:当前进程的别名,默认为Process-N,N为从1开始递增的整数

pid:当前进程的pid(进程号)

 

实例2- 打印进程pid

import multiprocessing

 

import os

import time

 

def run_proc():

    """子进程要执行的代码"""

    # os.getpid获取当前进程的进程号

    print('子进程运行中,pid=%d...' % os.getpid()) 

    print('子进程将要结束...')

 

if __name__ == '__main__':

    # os.getpid获取当前进程的进程号

    print('父进程pid: %d' % os.getpid()) 

    p = multiprocessing.Process(target=run_proc)

    p.start()

 

 

 

进程间不共享全局变量

 

多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响

 

 

from multiprocessing import Process

import os

import time

 

nums = [11, 22]

def work1():

    """子进程要执行的代码"""

    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))

    nums.append(33)

    time.sleep(1)

 

 

    print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))

def work2():

    """子进程要执行的代码"""

    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))

    nums.append(44)

    time.sleep(1)

    print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))

 

if __name__ == '__main__':

    p1 = Process(target=work1)

    p1.start()

    p1.join()

    p2 = Process(target=work2)

    p2.start()

    p2.join()

    nums.append(55)

    print("in main process pid=%d, nums=%s" % (os.getpid(), nums))

 

 

进程间通信:

Process之间有时需要通信,可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息队列程序

 

初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);

Process之间有时需要通信,可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息队列程序

初始化Queue()对象时(例如:q=Queue()),若括号中没有指定最大可接收的消息数量,或数量为负值,那么就代表可接受的消息数量没有上限(直到内存的尽头);

Queue.qsize():返回当前队列包含的消息数量;

Queue.empty():如果队列为空,返回True,反之False

Queue.full():如果队列满了,返回True,反之False

Queue.get([block[, timeout]]):获取队列中的一条消息,然后将其从列队中移除,block默认值为True

Queue.put(item,[block[, timeout]]):将item消息写入队列,block默认值为True

 

 

 

from multiprocessing import Process, Queue

import time

 

# 写数据进程执行的代码:

def write(q):

    for value in ['A', 'B', 'C']:

        print('Put %s to queue...' % value)

        q.put(value)

 

 

        time.sleep(1)

# 读数据进程执行的代码:

def read(q):

    while True:

        if not q.empty():

            value = q.get(True)

            print('Get %s from queue.' % value)

            time.sleep(1)

        else:

            break

if __name__=='__main__':

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

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

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

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

    pw.join()   # 等待pw结束:

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

    pr.join()

    print('所有数据都写入并且读完')