Python多线程

18.1 线程与进程的关系

程序是一些列的指令集,程序是静态的,当程序运行时,就会创建一个进程。
线程是进程的基本执行单元,一个进程至少要具有一个线程。

18.2 多线程

多线程,就类似与操作系统中的多进程。简单的讲,就是可以同时并发执行多个任务,处理多件事情

18.2.1 计算密集与IO密集

计算密集,是指在程序运行中,更多的时间为CPU在进行计算。而IO密集,则是更多的时间,在进行输入输出。
Python中,threading模块提供了关于线程的相关操作。

18.2.2 线程的创建

我们可以采用两种方式来创建线程:

  • 使用threading模块的Thread类,通过指定target与args(可选)参数。
  • 通过继承Thread类,重写run方法。

思考:直接调用run与调用start方法有什么不同?

线程的生命周期:
线程的生命周期可以分为以下环节:

  • 新建:创建对象
  • 就绪:调用start后
  • 运行:获得CPU资源
  • 阻塞(挂起):失去CPU资源
  • 死亡:线程执行结束或抛出未捕获的异常

18.2.3 线程相关操作

threading模块相关功能:

threading.active_count()
threading.enumerate()
threading.current_thread()
threading.get_ident()
threading.main_thread()

线程对象功能:

start()
run()
join(timeout=None)
name		setName / getName
ident
is_alive()
daemon		isDaemon() / setDaemon()

18.3 线程同步

18.3.1 并发修改的问题

当多线程并发运行时,多线程间很可能操作共享成员变量,此时,就需要对共享成员变量的操作进行同步,避免出现多线程的并发修改而引起的意外错误。

18.3.2 线程锁

我们可以通过threading.Lock()获得线程锁,来实现多个线程对共享区域的互斥访问。线程锁提供两个方法:

  • acquire():尝试去获得锁。
  • release():释放所获得的锁。

注意:要确保锁得到有效的释放。

18.3.3 死锁

当两个或多个线程同时拥有自己的资源,而相互等待获得对方资源,导致程序永远陷入僵持状态,这就是死锁。
当多线程并发访问共享数据时,使用线程锁可以避免多线程对共享变量并发修改带来的危害,但同时有可能会产生死锁。

18.4 线程队列

queue模块提供了队列的功能,该模块具有三个类:

  • queue.Queue(maxsize=0)
  • queue.LifoQueue(maxsize=0)
  • queue.PriorityQueue(maxsize=0)

队列类实现了内部的锁机制,因此,队列类型可以安全的用于多线程并发操作中。
其中,参数maxsize表示队列的最大元素个数,如果传递0或者负值,则表示无限容量。如果队列达到了最大容量,将会进行阻塞,直到有元素删除为止。
队列对象具有的方法如下:

qsize()
empty()
full()
put(item, block=True, timeout=None)
put_nowait(item)		put(item, False)
get(block=True, timeout=None)
get_nowait()			get(False)

18.5 习题

1.当创建一个线程时,该线程是前台线程还是后台线程?用代码验证一下。
2.编写两个线程,对同一个全局变量增加若干次(次数多一点),会出现什么情况。
3.两个线程,使用同一个函数作为target,然后在函数定义一个局部变量,两个线程分别对该变量自增若干次,会出现什么情况。
4.编写买家与卖家交易的程序,一个钱锁,一个货锁,并造成死锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值