python编程.多线程(threading模块或_thread模块)

前提

首先我们需要了解下我们为什么需要学习多线程,他有什么好处呢?
  1.使用线程可以把占据长时间的程序中的任务放到后台去处理。
  2.基本不会出现线程占用的问题。
  3.可以提高程序的运行效率

对于多线程的理解

  在多线程的程序中,主线程可以理解为一个饭店的前台,专门用来接待客人,当接收到任务的时候,主线程(前台)就会将任务送到厨房去,交给厨师们去处理(子线程),不会占用自己招待其他客人的时间。
  这样做还可以避免线程占用的问题。就比如说写一个服务器的程序,如果不是采用的多线程(异步调用)的方式的话,如果在主线程中还在运行上一个客人的请求的时候,又来了一个新的任务,那么主线程就无法去处理那个新的任务,导致webservice无法被调用,从而出现错误。

使用多线程的方式

  目前python中使用多线程的方式有两种,分别是采用threading模块,以及_thread模块。博主这里推荐大家去使用threading模块去写多线程的应用,因为threading模块几乎包含了_thread模块的所有方法并且在原来的基础上新增了很多的方法,可以说用_thread模块能做出来的,用threading模块也可以做出来。

使用_thread模块去写多线程

  我们可以调用_thread模块中的start_new_thread()函数来产生新的线程,语法如下:

thread.start_new_thread ( function, args, [kwargs])

·function - 想要在子线程运行的方法。
·args - 传递给线程函数的参数,传递的时候必须是个tuple类型。
·kwargs - 可选参数。

实例代码:

import time//引入时间模块
import _thread//引入_thread模块

//希望在多线程中运行的函数
def print_time(threadName,delay):
    count=0
    while count <3:
        count+=1
        time.sleep(delay)
        print(threadName+time.ctime(time.time()))
try:
    _thread.start_new_thread(print_time,("thread1",1))//将参数变成元组后传给函数
    _thread.start_new_thread(print_time,("thread2",2))//将参数变成元组后传给函数
//创建多线程失败
except:
    print("error")
while 1:
    pass//按ctrl+c结束程序

结果为:

thread1Sun Sep  1 20:22:03 2019
thread2Sun Sep  1 20:22:04 2019
thread1Sun Sep  1 20:22:04 2019
thread1Sun Sep  1 20:22:05 2019
thread2Sun Sep  1 20:22:06 2019
thread2Sun Sep  1 20:22:08 2019

使用threading模块去写多线程

1:

threading模块不仅包含了_thread模块中的所有方法,还包含了以下几种方法:

  threading.currentThread():
  返回当前的线程变量。(例如:写在主线程中就是返回的主线程)

  threading.enumerate():
  返回一个包含目前所有正在运行的线程的列表。

  threading.activeCount():
  返回正在运行的线程数量。

2:

  除了使用方法外,threading模块还提供了用来给线程类来处理线程的一些方法:

  run():
   用来表示线程具体活动的方法。

  start():
  启动目标线程。(开始调用目标的run()函数)

  join([time]):
  等待至线程中止或者是超出可选的参数:time。

  isAlive():
  返回目标线程是否活动的布尔值。

  getName():
  返回目标线程的名字。

  setName():
  设置线程的名字。

import time//引入time模块
import threading//引入threading模块

class myThread(threading.Thread):
    def __init__(self,threadID,name,counter):
        threading.Thread.__init__(self)
        self.threadID=threadID
        self.name=name
        self.couter=counter
    def run(self):
        print("开始线程"+self.name)
        print_time(self.name,self.couter,3)
        print("退出线程"+self.name)

def print_time(threadName,delay,counter):
        while counter:
            time.sleep(delay)
            print("%s:%s"%(threadName,time.ctime(time.time())))//显示当前时间
            counter-=1
//创建新线程
thread1=myThread(1,'thread1',1)
thread2=myThread(2,'thread2',2)
//开始线程
thread1.start() 
thread2.start()

print(threading.active_count())//显示当前处在运行状态的线程的数量(不同编译器出来的值也许会不同)
print(threading.enumerate())//显示当前所有在运行中的线程

thread1.join()//等待线程1结束
thread2.join()//等待线程2结束
print(threading.active_count())
print("退出主线程")

运行结果:(可能会不同)

开始线程thread1
开始线程thread2
9
[<_MainThread(MainThread, started 12024)>, <Thread(ptvsd.EventLoop, started daemon 3764)>, <Thread(ptvsd.Client, started daemon 11440)>, <WriterThread(pydevd.Writer, started daemon 10368)>, <ReaderThread(pydevd.Reader, started daemon 9624)>, <PyDBCommandThread(pydevd.CommandThread, started daemon 11816)>, <CheckOutputThread(pydevd.CheckAliveThread, started 2932)>, <myThread(thread1, started 5848)>, <myThread(thread2, started 7584)>]
thread1:Sun Sep  1 20:41:00 2019
thread2:Sun Sep  1 20:41:01 2019
thread1:Sun Sep  1 20:41:01 2019
thread1:Sun Sep  1 20:41:02 2019
退出线程thread1
thread2:Sun Sep  1 20:41:03 2019
thread2:Sun Sep  1 20:41:05 2019
退出线程thread2
7
退出主线程

总结

  python中的多线程我个人感觉使用起来还是很方便的,之前我也写过用C#去写多线程的文章,他的方法有很多种,有用委托的,有用Task的,有用Thread的,有用ThreadPool的,有用async、await的,方法各不相同,相比之下,python的看起来就简单一些。
  (PS:不知道为什么,明明是用的python去写的程序,原程序里也是正确的,但是我文章的注释还是忍不住用的“//”而不是“#”…)

发布了40 篇原创文章 · 获赞 80 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_19408097/article/details/100187082