Python多线程编程(三):threading模块的类与函数之基本类

主要参考文章:https://www.cnblogs.com/ArsenalfanInECNU/p/10134591.html

threading是python中用于线程相关操作的模块。python当前版本的多线程库没有实现优先级、线程组,线程也不能被停止、暂停、恢复、中断。本文章主要介绍threading模块的主要类与函数。

1.threading模块概览

threading模块提供的类:  
  Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。

threading 模块提供的常用方法: 
  threading.currentThread(): 返回当前的线程变量。 
  threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 
  threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

threading 模块提供的常量:

  threading.TIMEOUT_MAX 设置threading全局超时时间。

2.threading模块常用类

2.1 Thread类

Thread是线程类,有两种使用方法:方法一,直接在target传入要运行的方法;方法二,或从Thread继承并覆盖run()。推荐使用方法一,将目标函数作为target参数传入,非常简单。下面是两种使用方法:

方法一:

# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading

def sub_thread(arg):
    print("thread arg is :%s\n" % str(arg))

def run_thread():
    th_list = []
    for i in xrange(5):
        t = threading.Thread(target=sub_thread,args=(i,))
        th_list.append(t)
        t.start()
    for t in th_list:
        t.join()

if __name__ == '__main__':
    run_thread()

输出:

thread arg is :0
thread arg is :1
thread arg is :2
thread arg is :3
thread arg is :4

方法二:

# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
class MyThread(threading.Thread):
    def __init__(self, arg):
        super(MyThread, self).__init__()
        self.arg = arg
    def run(self):
        print("thread arg is: %s\n" % str(self.arg))

def run_thread():
    th_list = []
    for i in xrange(5):
        t = MyThread(i)
        th_list.append(t)
        t.start()
    for t in th_list:
        t.join()

if __name__ == '__main__':
    run_thread()

输出和方法一相同

Thread类的相关方法:

构造方法: 
Thread(group=None, target=None, name=None, args=(), kwargs={}) 

  group: 线程组,目前还没有实现,库引用中提示必须是None; 
  target: 要执行的方法; 
  name: 线程名; 
  args/kwargs: 要传入方法的参数。

实例方法: 
  isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。 
  get/setName(name): 获取/设置线程名。 

  start():  线程准备就绪,等待CPU调度
  is/setDaemon(bool): 将该子线程设置为父线程的守护线程(默认为非守护线程(False))。(需要在线程start之前设置)
  start(): 启动线程。 
  join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。

下面解释常用的实例方法:

2.1.1 关键参数setDaemon

该参数规定当前线程是否属于守护线程,需要在线程start之前设置,默认为非守护线程(False)。

  • True: 设置该子进程为父进程的守护进程,即后台线程。主线程执行过程中,子线程也在进行,主线程执行完毕后,子线程不论成功与否,主线程和子线程均停止。
  • False:设置该子进程为父进程的非守护进程,即前台进程。主线程执行过程中,子线程也在进行,主线程代码执行完毕后,仍需要等待子线程也执行完成后,主线程才会停止。

当线程设置为非守护线程时,主线程要等待所有子线程执行完之后,才停止程序。举例如下:

# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time

def daemon_test(arg):
    time.sleep(1)
    print("daemon thread args is: %s\n" % arg)

def run_daemon():
    th_list = []
    for i in xrange(5):
        t = threading.Thread(target=daemon_test, args=(i,))
        t.setDaemon(False)
        th_list.append(t)
        t.start()

if __name__ == '__main__':
    run_daemon()
    print("main process over")

输出为:

main process over
daemon thread args is: 4
daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 2

设置非线程守护时,主线程执行过程中,子线程也在进行,主线程执行完毕后,等待子线程也执行完成后,主线程停止。

当线程设置守护线程时:

# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time

def daemon_test(arg):
    time.sleep(1)
    print("daemon thread args is: %s\n" % arg)

def run_daemon():
    th_list = []
    for i in xrange(5):
        t = threading.Thread(target=daemon_test, args=(i,))
        t.setDaemon(True)
        th_list.append(t)
        t.start()

if __name__ == '__main__':
    run_daemon()
    print("main process over")

输出:

main process over

设置线程守护时,主线程执行完毕后,无论子线程执行与否,主线程和子线程均停止。

2.1.2 关键参数join

作用为阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。即当子进程的join()函数被调用时,主线程就被阻塞住了,意思为不再继续往下执行。

值得注意的是,由于join()会阻塞其他函数,如果我们要用for循环触发多个线程的执行,start()要和join()分开,即一次用两个for循环,先用第一个for循环将全部子线程start(),再用第二个for循环将全部子线程join,不然会让多线程并行执行,变成多线程依次执行:

  • 因为如果其他线程还没有start(),那么由于start()操作属于主线程的调用,那么start()会被阻塞,我们原本想要的多线程并行执行会变成多线程依次执行。
  • 如果此时其他线程已经start()了,那么join()函数由于是对子线程的操作,不属于主线程,则不会被阻塞。
# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import time

def join_test(arg):
    time.sleep(1)
    print("daemon thread args is: %s\n" % arg)

def run_join():
    th_list = []
    for i in xrange(5):
        t = threading.Thread(target=daemon_test, args=(i,))
        t.setDaemon(False)
        th_list.append(t)
        t.start()
    for t in th_list:
        t.join()

if __name__ == '__main__':
    run_join()
    print("main process over")

输出:

daemon thread args is: 1
daemon thread args is: 0
daemon thread args is: 3
daemon thread args is: 4
daemon thread args is: 2
main process over

2.2 Timer类

Timer(定时器)是Thread的派生类,用于在指定时间后调用一个方法。

构造方法: 
Timer(interval, function, args=[], kwargs={}) 
  interval: 指定的时间 
  function: 要执行的方法 
  args/kwargs: 方法的参数

实例方法: 
Timer从Thread派生,没有增加实例方法。

# /usr/bin/python3
# -*- coding: utf-8 -*-
import threading

def timer_test():
    print("timer thread start")


if __name__ == '__main__':
    t = threading.Timer(3, timer_test)
    t.start()

该例子为3秒之后调用函数

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章