threading:

    t.setDaemon(True)  将线程设置成守护线程,主进行结束后,此线程也会被强制结束。如果线程没有设置此值,则主线程执行完毕后还会等待此线程执行。

    t.join() 线程阻塞,只有当线程运行结束后才会继续执行后续语句

示例:

#coding: utf-8
import threading
import time def foo(name):
time.sleep(2)
print 'this is %s \n' % (name,) if __name__ == '__main__':
mythread = []
for i in range(5):
t = threading.Thread(target=foo, args=(i, ))
# t.setDaemon(True)
t.start()
mythread.append(t)
# for t in mythread:
# t.join()
print '-- end --'

运行结果(注意,print为非线程安全,所以打印内容有时会比较乱):

-- end --

this is 1

this is 2

this is 4

this is 0

this is 3

Process finished with exit code 0

可以看到,主线程和子线程是独立运行的(最后一行先被打印),主线程运行结束后依旧等待子线程结束。

把上面的t.setDaemon(True)取消注释,再运行一遍,发现只打印了如下内容:

-- end --

Process finished with exit code 0

即主线程运行结束后,会强制结束掉子线程

我们继续再把下面的注释去掉

# for t in mythread:

#     t.join()

再运行一遍,输出如下:

this is 1

this is 0

this is 3

this is 4

this is 2

-- end --

Process finished with exit code 0

注意:end在最后才被输出,说明在join那里阻塞了主线程的运行,在等待子线程运行完成。

queue:

       q.put(item) 将item放入队列中。

       q.get() 从队列中取出数据。

       q.task_done() 每次从queue中get一个数据之后,当处理好相关问题,最后调用该方法,以提示q.join()是否停止阻塞,让线程向前执行或者退出;

       q.join() 阻塞,直到queue中的数据已经每项已经task_done处理到空。

       如果不使用task_done也可以,可以通过q.full() q.empty()等来判断

 

 

q.join()隐藏的问题:

       对于生产者-消费者模型,这种阻塞方式是有漏洞的,因为如果queue初始为空,q.join()会直接停止阻塞,继续执行后续语句。

       还有另一种情况,就是生产者生产速度比较慢,而消费者消费速度比较快,也有可能停止阻塞,继续执行后续语句

       如果有多个消费者,没有生产者,且queue始初化为一定的数据量,则可以正常执行。

示例:

#coding: utf-8
import Queue
import threading
import time queue = Queue.Queue(maxsize=3) def produce():
for i in range(5):
item = "item" + str(i)
queue.put(item)
print "%s produce" % (item, )
# time.sleep(4) def customer():
while True:
time.sleep(2)
item = queue.get()
print "process %s finished" % (item, )
queue.task_done() if __name__ == '__main__':
t = threading.Thread(target=produce)
t.setDaemon(True)
t.start()
for i in range(3):
c = threading.Thread(target=customer)
c.setDaemon(True)
c.start()
queue.join()
print '-- end --'

运行输出如下:

item0 produce

item1 produce

item2 produce

process item0 finished

process item2 finishedprocess item1 finished

item3 produce

item4 produce

process item3 finished

process item4 finished

-- end --

Process finished with exit code 0

可以看到程序正常结束,end字符也在最后在打印出来。

我们把produce函数中注释掉如下语句,

queue.put(item)

print "%s produce" % (item, )

运行得到:

-- end --

Process finished with exit code 0

即queue为空,join()方法并不阻塞线程。

我们在produce函数中加上sleep,让生产慢一点,去掉time.sleep(4)前面的注释,运行得到:

item0 produce

process item0 finished

-- end --

Process finished with exit code 0

有时运行有可能会得到这样的错误信息:

Exception in thread Thread-3 (most likely raised during interpreter shutdown)

报错信息表明主线程不等待子线程就结束了。

可以发现,其实produce函数中应该还有任务要生成,但因为太慢,在join语句那里检测到队列为已经全部被设置task_done,就会继续往后执行,这有可能有时并不我们需要的,针对这样的情况,我们可以在queue.join()前加多一个子句t.join()即可达成目的。

如果我们再把customer函数中的queue.task_done()函数去掉,运行得到

item0 produce

process item0 finished

item1 produce

process item1 finished

item2 produce

process item2 finished

item3 produce

process item3 finished

item4 produce

process item4 finished

注意程序一直没有结束,而最后一行end语句也没有出现。因为在join那里,虽然队列已经全部为消费完,已经为0,但是由于它不是调用task_done函数而让其计数为0,所以此时,函数会一直阻塞在这里。

python threading queue模块中join setDaemon及task_done的使用方法及示例的更多相关文章

  1. 后台程序处理(二) python threading - queue 模块使用

    由于协程没办法完成(一)中所说的任务模式 接下来就尝试一下使用线程和队列来实现一下这个功能 在实现之前,我们先明确一个问题--python的线程是伪并发的.同一时间只能有一个线程在运行.具体怎样的运作 ...

  2. [转]Python多线程与多线程中join()的用法

    https://www.cnblogs.com/cnkai/p/7504980.html Python多线程与多进程中join()方法的效果是相同的. 下面仅以多线程为例: 首先需要明确几个概念: 知 ...

  3. python基础:os模块中关于文件/目录常用的函数使用方法

    Python是跨平台的语言,也即是说同样的源代码在不同的操作系统不需要修改就可以同样实现 因此Python的作者就倒腾了OS模块这么一个玩意儿出来,有了OS模块,我们不需要关心什么操作系统下使用什么模 ...

  4. Python的collections模块中namedtuple结构使用示例

      namedtuple顾名思义,就是名字+元组的数据结构,下面就来看一下Python的collections模块中namedtuple结构使用示例 namedtuple 就是命名的 tuple,比较 ...

  5. Python使用functools模块中的partial函数生成偏函数

    所谓偏函数即是规定了固定参数的函数,在函数式编程中我们经常可以用到,这里我们就来看一下Python使用functools模块中的partial函数生成偏函数的方法 python 中提供一种用于对函数固 ...

  6. 【转】在Python的struct模块中进行数据格式转换的方法

    这篇文章主要介绍了在Python的struct模块中进行数据格式转换的方法,文中还给出了C语言和Python语言的数据类型比较,需要的朋友可以参考下 Python是一门非常简洁的语言,对于数据类型的表 ...

  7. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  8. Python之Queue模块

    Queue 1.创建一个“队列”对象 >>> import Queue >>> queue = Queue.Queue(maxsize=100) >>& ...

  9. Python队列queue模块

    Python中queue模块常用来处理队列相关问题 队列常用于生产者消费者模型,主要功能为提高效率和程序解耦 1. queue模块的基本使用和相关说明 # -*- coding:utf-8 -*- # ...

随机推荐

  1. CTF---Web入门第八题 Guess Next Session

    Guess Next Session分值:10 来源: iFurySt 难度:易 参与人数:3870人 Get Flag:1672人 答题人数:1690人 解题通过率:99% 写个算法没准就算出来了, ...

  2. CTF---安全杂项入门第一题 丘比龙的最爱

    丘比龙的最爱分值:10 来源: 2014HCTF 难度:易 参与人数:4498人 Get Flag:1366人 答题人数:1384人 解题通过率:99% 传说,丘比龙是丘比特的弟弟,丘比龙是一只小爱神 ...

  3. Java A+B(个人模版)

    JavaA+B: import java.io.*; import java.util.*; import java.math.BigInteger; import java.util.Scanner ...

  4. [51nod1213]二维曼哈顿距离最小生成树

    二维平面上有N个坐标为整数的点,点x1 y1同点x2 y2之间的距离为:横纵坐标的差的绝对值之和,即:Abs(x1 - x2) + Abs(y1 - y2)(也称曼哈顿距离).求这N个点所组成的完全图 ...

  5. spring boot容器启动详解

    目录 一.前言 二.容器启动 三.总结 =======正文分割线====== 一.前言 spring cloud大行其道的当下,如果不了解基本原理那么是很纠结的(看见的都是约定大于配置,但是原理呢?为 ...

  6. hbase性能优化总结

    hbase性能优化总结 1. 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都 ...

  7. API接口签名验证2

    http://www.jianshu.com/p/d47da77b6419 系统从外部获取数据时,通常采用API接口调用的方式来实现.请求方和�接口提供方之间的通信过程,有这几个问题需要考虑: 1.请 ...

  8. css background之设置图片为背景技巧

    css background之设置图片为背景技巧-css 背景 Background是什么意思,翻译过来有背景意思.同样在css里面作为css属性一成员同样是有背景意思,并且是设置背景图片.背景颜色. ...

  9. php网站在服务器上邮件发送不了,在本地可以

    标签: php邮箱 2015-11-27 13:58 879人阅读 评论(0) 收藏 举报 分类: php(2) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在做phpmailer发送邮 ...

  10. 个人Vue-1.0学习笔记

    dVue.js是类似于angular.js的一套构建用户界面的渐进式框架,只关注视图层, 采用自底向上增量开发的设计. Vue.js的代码需要放置在指定的HTML元素后面. 关于Vue的数据绑定: 例 ...