Python多任务【多线程(两种创建方式)】

Python的标准库提供了两个模块:_threadthreading_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。Python的线程是真正的Posix Thread,而不是模拟出来的线程。

Python中threading模块

可以总结出:   

(1)当调用Thread的时候,不会创建线程

(2)调用Thread创建出来的实例对象的start方法的时候,才会创建线程以及让这个线程开始运行

         线程真正创建是调用start(),线程真正结束是主线程结束

(3)主线程会等待所有的子线程结束后才结束

(4)线程创建后谁先执行是不确定的,要确定先后的顺序可以通过延时的方式来保证

(5)只要主线程一死,其他的子线程就会全部结束

1.用threading创建多线程来执行任务

import time
import threading
def sing():
    print("---singing---")
    time.sleep(1)
    print(time.ctime())
if __name__ == '__main__':
    for i in range(5):
        t = threading.Thread(target = sing)
        t.start()
    

执行结果:1秒执行完毕,5个任务同时执行

t =  threading.Thread(target=函数名)   # 生成一个子线程对象,只生成对象,只有start后才是真正创建子线程

t.start()                                                  #  然后利用这个对象调用start()方法,,来创建一个子线程

2.在使用Thread时,线程是从什么时候开始创建的,什么时候结束

threading.enumerate() # 返回值是一个列表,里面有当前执行的所有线程 

threading.current_thread()    # 查看线程的名字 

import time
import threading
def sing():
    print("---singing---")
    time.sleep(1)
if __name__ == '__main__':
    #在调用Thread之前打印线程
    print(threading.enumerate())
    t = threading.Thread(target = sing)
    #在调用Thread之后打印线程
    print(threading.enumerate())
    #在调用start之后打印线程
    t.start()
    print(threading.enumerate())

 运行结果:

从结果可以看出线程真正被创建是在start执行之后,在只创建子线程对象时并没有创建线程。

3. 子线程是在创建Thread时执行的函数运行结束后结束    

import threading
import time
def test1():
    for i in range(3):
        print("----test1---%d---" % i)
        time.sleep(1)
    '''如果创建Thread时执行的函数运行结束,那么意味着 这个子线程就结束了'''
def test2():
    for i in range(6):
        print("----test2---%d---" % i)
        time.sleep(1)
def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)
    t1.start()
    t2.start()
    while True:
        #time.sleep(1)
        print(threading.enumerate())  # 打印出线程的列表
        '''所有的线程只剩一个的时候(即主线程)就退出'''
        if len(threading.enumerate()) <= 1:
            break
        time.sleep(1)
if __name__ == '__main__':
    main()
 

从结果可以分析出t1子线程是在执行三次test1函数后结束,t2子线程是在执行六次test2之后结束,不明白为什么在运行结果中存在了七次。

可得出:如果创建Thread时执行的函数运行结束,那么意味着这个子线程就结束了。

#疑问1:t2子线程是在执行六次test2之后结束,不明白为什么在运行结果中存在了七次。

#疑问2:为什么在打印线程时总是很乱的顺序,比如多行打印在一行;每次打印结果顺序都不一样;

4.通过继承Thread类完成创建线程

类里面覆写run()方法,用这个类的实例对象来调用start()方法

import threading
import time
class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            print(self.name)
    def login(self):
        pass
    '''
        如果类里面还有其他的方法想要用子线程,
        直接在run()方法里面调用就行(例如:self.login())
        如果直接用实例.方法名时,不会创建子线程,
    '''
if __name__ == '__main__':
    t = MyThread()
    t.start()  # 直接利用类的实例对象调用start()方法

5.利用threading创建线程时传入参数--args参数

args传递参数,参数指定的一定是一个元组类型

t = threading.Thread(target = 函数名,args = (1,2,) )

 

import time
import threading
def sing(name):
    print(time.ctime() + ' ' + name + " is singing!")
    time.sleep(1)
if __name__ == '__main__':
    names = ['YaoMing','Curry','Kobe','Durant','Jordan']
    for i in range(5):
        t = threading.Thread(target = sing,args = (names[i],))
        t.start()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值