python多任务之多线程

目录

线程等概念

 

创建线程

使用 _thread模块创建线程

使用 threading模块创建线程

多线程共享全局变量

线程同步

死锁

递归锁

递归锁和互斥锁的区别

GIL锁

什么是GIL?

GIL锁的缺陷

既然python在同一时刻下只能运行一个线程的代码,那线程之间是如何调度的呢? 

守护线程&非守护线程

银行家算法

在线程里,传递参数有三种方法

多线程版UDP简易聊天器

线程池

既然多线程可以缩短程序运行时间,那么,是不是线程数量越多越好呢?

使用线程池



线程等概念


并行
  多个任务同时执行,建立在多核CPU基础上。(4个人吃饭,有4套餐具,可以同时吃)

并发
  经过CPU的调度,快速的在单核CPU上多个任务的快速切换。(4个人吃饭,只有一套餐具,只能一个人一个人的吃)

 

进程
  (公司)
   资源单位,进程之间是相互独立的,进程自己是不能运行的,进程中的线程是负责执行和调度的,每个进程中默认都会有一个主线程

线程
  (公司里的人)
   执行单位

注意:进程的线程数 = 主线程 + 子线程

 

创建线程

Python3 线程中常用的两个模块为:

  • _thread
  • threading(推荐使用)

thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用"thread" 模块。为了兼容性,Python3 将 thread 重命名为 "_thread"。

 

使用 _thread模块创建线程

_thread基本方法:

_thread.start_new_thread(function,args,kwargs=None)    //派生一个新的线程,给定agrs和kwargs来执行function

_thread.allocate_lock()  //分配锁对象

_thread.exit()  //线程退出

lock.acquire(waitflag=1, timeout=-1)  //获取锁对象

lock.locked()  //如果获取了锁对象返回true,否则返回false

lock.release()  //释放锁

其他方法

_thread.LockType()  //锁对象类型

_thread.get_ident()  //获取线程标识符

-thread.TIMEOUT_MAX  //lock.acquire的最大时间,超时将引发OverflowError

_thread.interrupt_main()  //引发主线程KeyboardInterrupt错误,子线程可以用这个函数来终止主线程

 

调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:

_thread.start_new_thread ( function,args,kwargs=None )

参数说明:

  • function - 线程函数。
  • args - 传递给线程函数的参数,他必须是个tuple类型。
  • kwargs - 可选参数。
  •  

实例:

import _thread                                   
import time                                      
                                                 
                                                 
# 为线程定义一个函数                                      
def foo(threadName, sleepTime):                  
    count = 0                                    
    while count < 5:                             
        print('%s 正在执行' % threadName)            
        time.sleep(sleepTime)                    
        count += 1                               
                                                 
                                                 
# 创建线程                                           
try:                                             
   _thread.start_new_thread(foo, ('Thread1', 2)) 
   _thread.start_new_thread(foo, ('Thread2', 2)) 
except:                                          
    print('Error:无法启动线程')                        
                                                 
while 1:                                         
    pass                                         
                                                 

注意事项

_thread对于进程何时退出没有任何控制。当主线程结束时,所有其他线程也都强制结束。不会发出警告或者进行适当的清理。因而python多线程一般使用较为高级的threading模块,它提供了完整的线程控制机制以及信号量机制。

 

使用 threading模块创建线程

threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

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

除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

  • run(): 用以表示线程活动的方法。
  • start():启动线程活动。

     

  • join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
  • isAlive(): 返回线程是否活动的。
  • getName(): 返回线程名。
  • setName(): 设置线程名。

①直接使用threading.Thread类创建线程

注意:使用threading.Thread类创建线程时,主线程会进行收尾工作,即所有子线程执行完毕后,主线程才会结束

实例:创建两个子线程,要求先执行完线程1,在执行线程2

import threading
import time


def test1(threadName):
    for i in range(5):
        print('......第 %d 次打印 %s......' % (i, threadName))


def test2(threadName):
    for i in range(5):
        print('......第 %d 次打印 %s......' % (i, threadName))


# 创建线程,在java中调用start方法就使得线程进入就绪状态
thread1 = threading.Thread(target=test1, args=('线程1',))
thread2 = threading.Thread(target=test2, args=('线程2',))
"""
  第一个参数是函数名,第二个参数args是一个元组.
  特别注意其中的逗号不能少,少了就不是元组了,就会报错。
"""

# 启动线程
thread1.start()
time.sleep(1)  # 将主线程休眠 1秒钟, 以便先执行完 thread1
print('-' * 30)
thread2.start()


 

②继承Thread创建线程

注意:必须重写 run()方法

 

import threading
import time


class MyThread(threading.Thread):
    def __init__(self, thread_name):
        threading.Thread.__init__(self)  # 没有该语句的话则会出现Python RuntimeError: thread.__init__() not called异常
        self.thread_name = thread_name

    def run(self):
        for i in range(5):
            print('......第 %d 次打印 %s......' % (i, self.thread_name))


# 创建线程
thread1 = MyThread('线程1')
thread2 = MyThread('线程2')

# 启动线程
thread1.start()
time.sleep(1)
print('-' * 30)
thread2.start()











 

多线程共

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值