集团主站
欢迎来到成都达内官方网站!达内—美国上市公司 亿元级外企IT培训企业!
成都it培训哪家好
成都it培训哪家好
全国服务监督电话:15023458194  |   联系客服   |
当前位置:主页 > 培训课程 > Python >

[成都Python培训机构排名]如何改变Python中线程的执行顺序

发布者: 成都达内     浏览次数:     发布时间:2020-09-23 10:21:29

[成都Python培训机构排名]如何改变Python中线程的执行顺序,一、主线程会等待所有的子线程结束后才结束,首先我看下最普通情况下,主线程和子线程的情况。...

  一、主线程会等待所有的子线程结束后才结束

  首先我看下最普通情况下,主线程和子线程的情况。

  import threading

  from time import sleep, ctime

  def sing():

  for i in range(3):

  print("正在唱歌...%d" % i)

  sleep(1)

  def dance():

  for i in range(3):

  print("正在跳舞...%d" % i)

  sleep(1)

  if __name__ == '__main__':

  print('---开始---:%s' % ctime())

  t1 = threading.Thread(target=sing)

  t2 = threading.Thread(target=dance)

  t1.start()

  t2.start()

  print('---结束---:%s' % ctime())

  运行结果:

  [成都Python培训机构排名]如何改变Python中线程的执行顺序

  最后一行打印的代码就算在一开始运行了,程序也不会结束。

  只有等待所有的子线程(sing 和 dance)都执行完毕,主线程才会结束,即程序结束。

  二、默认状态下,多线程的执行顺序是不确定的

  我们先来看一段代码:

  import threading

  import time

  class MyThread(threading.Thread):

  def run(self):

  for i in range(3):

  time.sleep(1)

  msg = "I'm "+self.name+' @ '+str(i)

  print(msg)

  def test():

  for i in range(5):

  t = MyThread()

  t.start()

  if __name__ == '__main__':

  test()

  运行结果:

  I'm Thread-1 @ 0

  I'm Thread-2 @ 0

  I'm Thread-3 @ 0

  I'm Thread-4 @ 0

  I'm Thread-5 @ 0

  I'm Thread-1 @ 1

  I'm Thread-3 @ 1

  I'm Thread-2 @ 1

  I'm Thread-4 @ 1

  I'm Thread-5 @ 1

  I'm Thread-1 @ 2

  I'm Thread-3 @ 2

  I'm Thread-2 @ 2

  I'm Thread-4 @ 2

  I'm Thread-5 @ 2

  每次的运行结果可能都不一样,但大体差不多。

  说明:

  从代码和执行结果我们可以看出,多线程程序的执行顺序是不确定的。

  当执行到 sleep 语句时,线程将被阻塞,到 sleep 结束后,线程进入就绪状态,等待调度,而线程调度将自行选择一个线程执行。

  上面的代码中只能保证每个线程都运行完整个 run 函数,但是线程的启动顺序、run 函数中每次循环的执行顺序都不能确定。

  总结

  每个线程默认有一个名字,尽管上面的例子中没有指定线程对象的 name,但是 python 会自动为线程指定一个名字。

  当线程的 run() 方法结束时该线程完成。

  无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。

  三、Python daemon 守护线程详解

  当程序中拥有多个线程时,主线程执行结束并不会影响子线程继续执行。

  换句话说,只有程序中所有线程全部执行完毕后,程序才算真正结束。

  Python 还支持创建另一种线程,称为守护线程(或后台线程)。

  此类线程的特点是,当程序中主线程及所有非守护线程执行结束时,未执行完毕的守护线程也会随之消亡,程序将结束运行。

  守护线程本质也是线程,因此其创建方式和普通线程一样,唯一不同之处在于,将普通线程设为守护线程,需通过线程对象调用其 damon 属性,将该属性的值改为 True。

  注意:线程对象调用 daemon 属性必须在调用 start() 方法之前,否则 Python 解释器将报 RuntimeError 错误。

  import threading

  def action(len):

  for i in range(len):

  print(threading.current_thread().getName() + "," + str(i))

  def main():

  t1 = threading.Thread(target=action, args=(10,))

  # 设置子线程为守护进程

  t1.daemon = True

  t1.start()

  for i in range(3):

  print(threading.current_thread().getName()+','+str(i))

  if __name__ == "__main__":

  main()

  运行结果:

  Thread-1,0

  MainThread,0

  MainThread,1

  MainThread,2

  程序中,子线程里的程序就循环了一次,接着主线程执行完后,子线程就不打印信息了。

  由于该程序中除了守护线程就只有主线程,因此只要主线程执行结束,则守护线程也随之消亡。

  四、控制线程执行顺序

  通过前面的学习我们知道,主线程和子线程会轮流获得 CPU 的资源。

  但有时候,我们想让某个子线程先执行,然后再让主线程执行代码,该如何实现呢?

  很简单,通过调用线程对象的 join() 方法即可。

  join() 方法的功能是在程序指定位置,优先让该方法的调用者使用 CPU 资源。

  该方法的语法格式如下:

  thread.join( [timeout] )

  timeout 参数作为可选参数,其功能是指定 thread 线程最多可以霸占 CPU 资源的时间(以秒为单位)。

  如果省略,则默认直到 thread 执行结束(进入死亡状态)才释放 CPU 资源。

  我们仍旧拿上面的例子来举例:

  import threading

  def action(len):

  for i in range(len):

  print(threading.current_thread().getName() + "," + str(i))

  def main():

  t1 = threading.Thread(target=action, args=(10,))

  # 设置子线程为守护进程

  t1.daemon = True

  t1.start()

  t1.join()

  for i in range(3):

  print(threading.current_thread().getName()+','+str(i))

  if __name__ == "__main__":

  main()

  我们在子线程调用的后面,添加了 t1.join()。

  运行结果:

  Thread-1,0

  Thread-1,1

  Thread-1,2

  Thread-1,3

  Thread-1,4

  Thread-1,5

  Thread-1,6

  Thread-1,7

  Thread-1,8

  Thread-1,9

  MainThread,0

  MainThread,1

  MainThread,2

  上面的例子中,t1 线程调用了 join() 方法,并且没有指定具体的 timeout 参数值。

  这意味着如果程序想继续往下执行,必须先执行完 t1 子线程。

(责任编辑:范老师)
最新开班
  • 成都Java培训班
    免费试听名额发放中...
  • 成都C++培训班
    免费试听名额发放中...
  • 成都PHP培训班
    免费试听名额发放中...
  • 成都网络工程培训班
    免费试听名额发放中...
  • 成都Unity3D培训班
    免费试听名额发放中...
  • 成都大数据培训班
    免费试听名额发放中...
  • 成都uid培训班
    免费试听名额发放中...
  • 成都会计培训班
    免费试听名额发放中...
  • 成都Python培训班
    免费试听名额发放中...
  • 成都嵌入式培训班
    免费试听名额发放中...
  • 成都web培训班
    免费试听名额发放中...
  • 成都软件测试培训班
    免费试听名额发放中...
在线留言
提交

校区地址:成都市锦江区东大街紫东楼端35号明宇金融广场19楼1906室

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市高新区奥克斯广场蜀锦路209号一楼商铺

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都锦江区东大街芷泉街229号东方广场C座3楼303

联系电话:15023458194

公交路线:芷泉街(188路;115路;515路;236路;505路;501路;84路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市武侯区佳灵路3号红牌楼广场2号写字楼11楼1115号

联系电话:15023458194

公交路线:红牌楼东(11路;92路;100路;111路;139路;g28路;快速公交K1/K2) 地铁路线:红牌楼站(地铁3号线)

校区地址:成都市锦江区红星路二段70号四川日报大厦502-2

联系电话:15023458194

公交路线:市二医院站(6路;49路;102路;5路;37路;g92路;) 地铁路线:地铁市二医院(地铁3号线)

校区地址:成都市锦江区东大街芷泉段229号东方广场C座16层

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:四川省成都市武侯区高新科技孵化园9号园区E座7楼

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都市高新区奥克斯广场B座1708

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

了解达内动态
关注成都达内教育公众号

首页 | 关于达内 | 课程中心 | 专家师资 | 视频教程 | 学员空间 | 校企合作 | 新闻资讯 | 就业指导 | 网站地图

2016-2025 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56