4-7

181 阅读3分钟

多线程总结

多线程

  • Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。
  • 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。

创建一个进程

import time, threading

新线程执行的代码:

def loop():
    print('thread %s is running...' % threading.current_thread().name)
    n = 0
    while n < 5:
        n = n + 1
        print('thread %s >>> %s' % (threading.current_thread().name, n))
        time.sleep(1)
    print('thread %s ended.' % threading.current_thread().name)

print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target=loop, name='LoopThread')
t.start()
t.join()

print('thread %s ended.' % threading.current_thread().name)
  • current_thread()函数: 它永远返回当前线程的实例。主线程实例的名字叫MainThread,子线程的名字在创建时指定,我们用LoopThread命名子线程。名字仅仅在打印时用来显示,完全没有其他意义,如果不起名字Python就自动给线程命名为Thread-1,Thread-2……

  • start(): 开始线程活动。

  • setDaemon()   setDaemon(True)将线程声明为守护线程,必须在start() 方法调用之前设置,如果不设置为守护线程程序会被无限挂起。子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print "all over %s" %ctime()后,没有等待子线程,直接就退出了,同时子线程也一同结束。

  • join: 用于等待线程终止。join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

  注意: join()方法的位置是在for循环外的,也就是说必须等待for循环里的两个进程都结束后,才去执行主进程。

创建自己的多线程类

#coding=utf-8
import threading 
from time import sleep, ctime 
 
class MyThread(threading.Thread):

    def __init__(self,func,args,name=''):
        threading.Thread.__init__(self)
        self.name=name
        self.func=func
        self.args=args
    
    def run(self):
        apply(self.func,self.args)


def super_play(file,time):
    for i in range(2):
        print 'Start playing: %s! %s' %(file,ctime())
        sleep(time)


list = {'爱情买卖.mp3':3,'阿凡达.mp4':5}

#创建线程
threads = []
files = range(len(list))

for k,v in list.items():
    t = MyThread(super_play,(k,v),super_play.__name__)
    threads.append(t)        

if __name__ == '__main__': 
    #启动线程
    for i in files:
        threads[i].start() 
  for i in files:
      threads[i].join()

    #主线程
    print 'end:%s' %ctime()
  • MyThread(threading.Thread)

创建MyThread类,用于继承threading.Thread类。

  • init()

使用类的初始化方法对func、args、name等参数进行初始化。

  • apply()

  apply(func [, args [, kwargs ]]) 函数用于当函数参数已经存在于一个元组或字典中时,间接地调用函数。args是一个包含将要提供给函数的按位置传递的参数的元组。如果省略了args,任何参数都不会被传递,kwargs是一个包含关键字参数的字典。

appply的应用

#不带参数的方法
>>> def say():
    print 'say in'

>>> apply(say)
say in

#函数只带元组的参数
>>> def say(a,b):
    print a,b

>>> apply(say,('hello','虫师'))
hello 虫师

#函数带关键字参数
>>> def say(a=1,b=2):
    print a,b

    
>>> def haha(**kw):
    apply(say,(),kw)

    
>>> haha(a='a',b='b')
a b