Python多线程

1.多线程类似于使用计算机的一个核心执行不同的任务,好处如下:

  • 使用线程可以把需要使用大量时间的计算任务放到后台去处理
  • 减少资源占用,加快程序的运行速度

2.操作线程的模块threading,相对于Python既有的多线程模块,threading重写了部分API模块,对thread进行了二次封装,大大提高了执行效率,并且重写了更为方便的API来处理线程。

3.threading的使用
threading.Thread:这个类可以可以被子类以有限的样式继承。有两种具体的方法:

  • (1)方法1:

    • 传递可调用的对象:
    t = threading.Thread(target=None,args=(),kwargs=None)
    
    target:是可以被run()方法调用的对象,默认为None。
    args:供target调用的元组元素,默认为()
    kwargs:供target调用的关键字元素,默认为{}
    
    • 示例:
     import time
     import threading
     
     def func1(str):
         print("func1 start!",time.ctime())
         print(str)
         time.sleep(4)
         print("func1 end!",time.ctime())
     
     def func2(str):
         print("func2 start!",time.ctime())
         print(str)
         time.sleep(3)
         print("func2 end!",time.ctime())
     
     
     def main():
         t1 = threading.Thread(target=func1,args=("情人节",))
         t1.start()
         #t1和t2给参数的方法均可,但是args只有一个参数时必须有 , 否则报错
         t2 = threading.Thread(func2("快乐"))
         t2.start()
     
     if __name__ == "__main__":
         main()
         
         
     Output:
     func1 start! Wed Aug  7 11:01:30 2019
     func2 start! Wed Aug  7 11:01:30 2019
     情人节
     快乐
     func2 end! Wed Aug  7 11:01:33 2019
     func1 end! Wed Aug  7 11:01:34 2019
    
  • (2)方法2:

    import threading
    import time
    
    count = 0
    class MyThread(threading.Thread):
        def __init__(self):
            super(MyThread,self).__init__()
            #threading.Thread.__init__(self)   也可以
    
        #重写run方法
        def run(self):
            global count
    
            for i in range(6):
                #防止程序执行太快无法看到过程
                time.sleep(0.5)
                #打印线程名称
                print(self.getName(), count)   
                count += 1
    
    if __name__ == '__main__':
        threadList = []
        
        for i in range(2):
            threadList.append(MyThread())
        for single_thread in threadList:
            single_thread.start()
       
       
            
    Output:
    Thread-2 0
    Thread-1 0
    Thread-2 2
    Thread-1 2
    Thread-2 4
    Thread-1 5
    Thread-1 6
    Thread-2 6
    Thread-2 8
    Thread-1 8
    Thread-2 10
    Thread-1 10
    
    #可以看出,程序在运行过程中,两个线程同时对一个数进行操作,并将结果打印。
    #但是出现应该逐次打印的数据变成了两个相同的数值,我们可以用threading中的Lock类解决。
    
    • 利用Lock类解决打印数值相同的问题:Lock类作用是对当前运行中的线程进行锁定,只有当前的线程被释放后,后序的线程才能继续操作。
    import threading
    import time
    
    count = 0
    #添加Lock对象
    lock = threading.Lock()
    class MyThread(threading.Thread):
        def __init__(self):
            super(MyThread,self).__init__()
            self.lock = lock
        #重写run方法
        def run(self):
            global count
            #确定对象被锁定的标志
            self.lock.acquire()
            for i in range(6):
                # count += 1
                time.sleep(0.5)
                print(self.getName(), count)
                count += 1
            #释放当前对象
            self.lock.release()
    
    if __name__ == '__main__':
        threadList = []
    
        for i in range(2):
            threadList.append(MyThread())
        for single_thread in threadList:
            single_thread.start()
            
            
    Output:
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    Thread-1 5
    Thread-2 6
    Thread-2 7
    Thread-2 8
    Thread-2 9
    Thread-2 10
    Thread-2 11
    
    #可以看出,Thread-1结束后再执行Thread-2
    
    • threading中的join类:作用是阻止全部的线程继续运行,知道被调用的线程执行完毕或者超时。
    import threading
    import time
    
    def join_wait():
        print("start waiting:", time.ctime())
        time.sleep(3)
        print("stop waiting:", time.ctime())
    
    thread_1 = threading.Thread(target=join_wait)
    thread_1.start()  # 启动线程
    print("start join",time.ctime())
    thread_1.join()   #将主线程阻塞,知道thread_1结束再往下执行
    print("end join",time.ctime())
    
    
    Output:
    start waiting: Wed Aug  7 12:52:48 2019
    start join Wed Aug  7 12:52:48 2019
    end join Wed Aug  7 12:52:48 2019
    stop waiting: Wed Aug  7 12:52:51 2019
    
  • 线程中的一些方法:

    • isAlive():查看线程是否是活动的,返回值是bool类型。
    #利用帮助函数查询
    help(threading.Thread.is_alive)
    
    Output:
    is_alive(self)
         Return whether the thread is alive.
         
         This method returns True just before the run() method start
         until just after the run() method terminates. 
         The module function enumerate() returns a list of all alive threads.
    

    1.即在run方法执行开始到结束时,认为线程是活动的。

    2.模块函数enumerate()返回所有活动的线程。

    • getName():获取线程名称,样式是Thread-No
    • setName():设置线程名称
     import threading
     t = threading.Thread()
     t.setName("T1")
     print(t.getName())
     
     Output:T1
    
    • run():代表线程活动的方法
      可以在子类中重写这个方法,标准的run()方法调用回调对象传递给构造函数的target元素。
    • setDaemon(daemonic):将线程设置为守护线程,说明该线程不重要,在进程退出的时候不用等待这个线程退出。
     import time
     import threading
     
     def func():
         print("start func")
         time.sleep(2)
         print("end func")
     
     print("start main thread")
     t = threading.Thread(target=func)
     t.setDaemon(True)    #将线程设置为守护线程
     t.start()
     time.sleep(1)
     print("end main thread")
     
     Output:
     start main thread
     start func
     end main thread
     
     #由结果,线程t设置为守护线程,未执行完就退出了
    
    有任何问题可以留言小g
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值