weiqi7777

python的多线程与多进程

0
阅读(2743)

         python使用threading库,可以实现多线程,使用multiprocessing库实现多进程。

一、            多线程

         python使用 threading 库来实现多线程。

         threading自带的方法:

clip_image002

         其中有一个方法,

enumerate() :获取当前所有子线程,返回子线程的列表。

该列表,至少会有一个元素,就是主线程。

clip_image004

 

         threading库下有Thread类,创建多线程。

         对于Thread类,有如下的几个属性以及方法:

clip_image006

name

线程的名字

setDaemon()

设置线程是否是deamon线程,传参为True或者False,默认是False。如果线程是守护线程,那么进程结束后,该线程也会被结束。

getName()

获取线程的名字

setName()

设置线程的名字

is_alive()

线程是否有效

join([timeout])

该方法会将主调线程阻塞,知道该线程执行完毕后,主线程才会执行。timeout是一个超时时间。

start()

启动线程

run()

线程启动之后执行的函数,可以重载该函数

 

         多线程,有两种方法实现,一种是用函数,一种是用类。

1.    函数实现

import threading

import time

import os

 

def say_hello():

    pid = os.getpid()

    for i in range(5):

        print( str(pid) + ': ' + str(i) + '\n' )

        time.sleep(2)

 

for i in range(5):

    th = threading.Thread(target=say_hello,args=())

    th.start()

 

th_list = threading.enumerate()

print (th_list)

 

for a in th_list:

    print(a.name)

 

time.sleep(20)

         通过threadingThread类,创建了5个类。target指定线程执行函数,args表示给线程传递的参数。

         通过threading.emuerate()获取当前执行的线程。

         th_list是线程列表,总共有7个线程,一个主线程,MainThread,一个守护进程,SockThread5个子线程,Thread-1 – Thread-5

clip_image008

         左图是打印的线程的名字,右图是线程执行的打印信息。

         对于线程,所有线程的PID都是一样的。

clip_image009       clip_image010

2.    类实现

         将子线程,实现在类中,该类,继承threading.Thread类。并且重载run方法,这样当调用类的start方法后,会自动调用run方法。

         注意在__init__方法中,要执行父进程的__init__方法。

import threading

import time

import os

 

class say_hello(threading.Thread):

    def __init__(self):

        threading.Thread.__init__(self)

 

    def run(self):

        pid = os.getpid()

        for i in range(5):

            print( str(pid) + ': ' + str(i) + '\n' )

            time.sleep(2)

 

for i in range(5):

    th = say_hello()

    th.start()

 

th_list = threading.enumerate()

print (th_list)

 

for a in th_list:

    print(a.name)

 

time.sleep(20)

         执行效果:

         当前执行的所有线程。

clip_image012

         左图是打印的线程的名字,右图是线程执行的打印信息。

         对于线程,所有线程的PID都是一样的。

clip_image013     clip_image014

二、            多进程

         python使用multiprocessing库来是实现多进程

clip_image016

         multiprocessing库下有一个方法:     

         active_children() 获取当前的所有子进程,返回子进程列表。

         该列表,在没有子进程时,返回空列表。

clip_image017

 

         Queue类,实现进程间的数据传递通信。一个Queue可以连接多个进程。比如可以将父进程和所有的子进程,用Queue进行连接,实现父子进程之间的通信。Queue的大小可以无限大,在例化Queue的时候指定。

         Queue(5), 指定Queue的大小为5

            Queue(),  Queue无限大

         Queue在多线程之间,也可以用于通信。

Queue有三个常用方法:

empty()

Queue是否空,即是否有数据在Queue中。

put(data, block=, timeout= )

data放入到Queue中,block有两个选项,True表示如果put不成功,就阻塞。False表示即使put不成功,也不会阻塞。timeout指阻塞的最大时间。

get(block=,timeout)

Queue中获取数据。返回获取的数据。block有两个选项,True表示如果get不成功,就阻塞。False表示即使get不成功,也不会阻塞。timeout指阻塞的最大时间。

 

         multiprocessing库下有Process类,创建子进程。

         对于Process类,有如下一些属性和方法:

clip_image019

name

进程的名字

pid

进程的pid

daemon

进程是否是守护进程,True或者False。如果是守护进程,主进程结束之后,守护进程将会被结束

is_alive()

进程是否有效

start()

启动子进程

run()

子进程启动之后执行的方法,可以重载该方法

terminater()

终止该进程

join(timeout)

阻塞父进程,直到子进程执行完毕后,父进程才可执行。timeout指定最多阻塞父进程的时间

 

         多进程,有两种方法实现,一种是用函数,一种是用类。

1.    函数实现

         使用multiprocessing下的Process类,创建一个对象,传入target参数为say_hello函数。调用对象的start方法,该方法会自动调用传入的say_hello函数。

import multiprocessing

import time

import os

 

def say_hello():

    pid = os.getpid()

    print ("child")

    for i in range(5):

        print( str(pid) + ': ' + str(i) + '\n' )

        time.sleep(2)

 

for i in range(5):

    pr = multiprocessing.Process(target=say_hello,args=())

    pr.start()

 

pr_list = multiprocessing.active_children()

print (pr_list)

 

for a in pr_list:

    print(a.name)

time.sleep(20)

         window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。

         对于进程列表,保存的是所有子进程的进程列表。

clip_image021

 

         linux下执行,进程列表,进程名,进程执行结果都会打印。

         对于不同的子进程,PID是不一样的。

clip_image023

 

2.    类实现

将子线程,实现在类中,该类,继承multiprocessing.Process类。并且重载run方法,这样当调用类的start方法后,会自动调用run方法。

         注意在__init__方法中,要执行父进程的__init__方法。

import multiprocessing

import time

import os

 

 

class say_hello(multiprocessing.Process):

    def __init__(self):

        multiprocessing.Process.__init__(self)

 

    def run(self):

        pid = os.getpid()

        print ("child")

        for i in range(5):

            print( str(pid) + ': ' + str(i) + '\n' )

            time.sleep(2)

 

for i in range(5):

    pr = say_hello()

    pr.start()

 

pr_list = multiprocessing.active_children()

print (pr_list)

 

for a in pr_list:

    print(a.name)

time.sleep(20)

window下执行,只会打印进程列表,以及进程的名字。而进程的执行结果不会打印。

         对于进程列表,保存的是所有子进程的进程列表。进程的名字,默认为是class的名字。

clip_image025

         linux下执行,进程列表,进程名,进程执行结果都会打印。

         对于不同的子进程,PID是不一样的。

clip_image027