关于python多线程编程中join()和setDaemon()的一点儿探究
关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧。
首先是编写实验的基础代码,创建一个名为MyThread的 类,然后通过向这个类传入print_func这个方法,分别创建了两个子线程:
#!/usr/bin/env python
import threading
import time class MyThread(threading.Thread): def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name=name
self.func=func
self.args=args def run(self):
apply(self.func, self.args) def print_func(num): while True:
print "I am thread%d" % num
time.sleep(1) threads = []
t1 = MyThread(print_func, (1, ), print_func.__name__)
threads.append(t1)
t2 = MyThread(print_func, (2, ), print_func.__name__)
threads.append(t2)
首先来试试setDaemon()的设置,在上面基础代码的后面加上以下的代码:
for t in threads:
t.setDaemon(True)
t.start() print "ok\n"
程序输出:
I am thread1
I am thread2
ok
print_func()中的while循环没有继续执行下去就退出了,可见由于setDaemon(True)把子线程设置为守护线程,子线程启动后,父线程也继续执行下去,当父线程执行完最后一条语句print "ok\n"后,没有等待子线程,直接就退出了,同时子线程也一同结束。
下面我们把添加的代码更改如下:
for t in threads:
t.start()
t.join() print "ok\n"
这个时候程序会输出:
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
。。。
这样一直循环下去,可见只有第一个子线程被调用了,第二个子线程,以及父线程都没有继续走下去。这里我的理解是:join()的作用是,在子线程完成运行之前,这个子线程的父线程将一直被阻塞。,无法运行下去。在这里父线程没法继续执行for循环,所以第二个子线程也就不会出现了。
接下来再修改一下代码:
for t in threads:
t.start() for t in threads:
t.join() print "ok\n"
这时程序输出:
I am thread1
I am thread2
I am thread1
I am thread2
I am thread1
I am thread2
I am thread1
。。。
可见这个时候两个子线程都在运行了,同样在两个子线程完成之前,父线程的print "ok\n"都不会执行。
之前的实验中,两个子线程的运行时间是一样的,那么假如两个线程耗时不一样,一个子线程先于另一个子线程完成执行,会发生什么情况呢,于是我增加了一个什么都不干的方法pass_func:
#! /usr/bin/env python
#coding=utf-8
import threading
import time class MyThread(threading.Thread): def __init__(self, func, args, name=''):
threading.Thread.__init__(self)
self.name=name
self.func=func
self.args=args def run(self):
apply(self.func, self.args) def print_func(num): while True:
print "I am thread%d" % num
time.sleep(1) def pass_func():
pass threads = []
t1 = MyThread(print_func, (1, ), print_func.__name__)
threads.append(t1)
t2 = MyThread(pass_func, (), pass_func.__name__)
threads.append(t2) for t in threads:
t.start() for t in threads:
t.join() print "ok\n"
这段代码的执行结果是:
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
I am thread1
。。。
可见这时侯,一个子线程的完成不会影响另外一个子线程,父线程仍然一直被阻塞着。
有些时候,还可以单独对某一个子线程设定join(),以达到特定的效果,例如下面这段代码片段的用意是,分别设立一个子线程用于接收数据,另外一个子线程用于发送数据,当用户输入“quit”时,程序退出:
def send(sck):
while True:
data = raw_input('>')
sck.send(data)
if data == "quit":
sck.close()
break def recieve(sck):
while True:
data = sck.recv(BUFSIZ)
print data, "\n"
threads = []
t1 = threading.Thread(target=send, args = (tcpCliSock, ))
threads.append(t1)
t2 = threading.Thread(target=recieve, args = (tcpCliSock, ))
threads.append(t2) for t in threads:
t.start()
t1.join()
这段代码中,把t1,也就是send所对应的子线程添加上join()属性,让父线程在send方法对应的子线程结束前一直在阻塞状态。假如把两个子线程t1和t2都添加上join()属性,这会使得send方法收到“quit”命令,退出循环后,由于recieve方法仍然在循环当中,父线程仍然被阻塞着,结果程序无法退出。只对t1添加join()属性,那么t1结束了,父线程会继续执行下去,直到执行完最后一条代码后退出,然后t2也跟着一同结束,达到所有线程都退出的目的,这就是t1.join()这条命令的用意。
关于python多线程编程中join()和setDaemon()的一点儿探究的更多相关文章
- python多线程编程
Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...
- 【C/C++开发】多线程编程中的join函数
多线程编程中的join函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # coding: utf-8 # 测试多线程中join的 ...
- day-3 python多线程编程知识点汇总
python语言以容易入门,适合应用开发,编程简洁,第三方库多等等诸多优点,并吸引广大编程爱好者.但是也存在一个被熟知的性能瓶颈:python解释器引入GIL锁以后,多CPU场景下,也不再是并行方式运 ...
- Java多线程编程(2)--多线程编程中的挑战
一.串行.并发和并行 为了更清楚地解释这三个概念,我们来举一个例子.假设我们有A.B.C三项工作要做,那么我们有以下三种方式来完成这些工作: 第一种方式,先开始做工作A,完成之后再开始做工作B ...
- Java多线程编程中Future模式的详解
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- C++ 关于MFC多线程编程中的一些注意事项 及自定义消息的处理
在多线程编程中,最简单的方法,无非就是利用 AfxBeginThread 来创建一个工作线程,看一下这个函数的说明: CWinThread* AFXAPI AfxBeginThread( AFX_T ...
- Java多线程编程中Future模式的详解<转>
Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Futu ...
- Qt多线程编程中的对象线程与函数执行线程
近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...
- C#多线程编程中的锁系统
C#多线程编程中的锁系统(二) 上章主要讲排他锁的直接使用方式.但实际当中全部都用锁又太浪费了,或者排他锁粒度太大了. 这一次我们说说升级锁和原子操作. 目录 1:volatile 2: Inter ...
随机推荐
- Python 中使用optparse进行参数解析
使用过Linux/Unix的人都会知道,命令行下的很多命令都需要参数,在C语言中添加和解析参数比较繁琐.Python中提供了optparse模块可以非常方便地处理命令行参数. 1 命令行参数的样 ...
- SQL Server网络地址备份
SQL Server网络地址备份 Ø 软件系统: SQL Server 各版本 1.问题描述: 在XX客户做SQL Server 到Oracle 数据迁移时,当时由于客户的SQL Server200 ...
- LeetCode 3
Longest Substring Without Repeating Characters Given a string, find the length of the longest substr ...
- MakeFile 文件详解
GNU的make工作时的执行步骤入下:(想来其它的make也是类似) 1.读入所有的Makefile. 2.读入被include的其它Makefile. 3.初始化文件中 ...
- nmap命令-----高级用法
探测主机存活常用方式 (1)-sP :进行ping扫描 打印出对ping扫描做出响应的主机,不做进一步测试(如端口扫描或者操作系统探测): 下面去扫描10.0.3.0/24这个网段的的主机 nmap ...
- Angular 全局页面切换动画 me-pageloading
最近看了Codrops的一篇文章, 里面讲到了一个页面切换的效果, 详情点击此处. 看了这个效果感觉很赞, 觉得这个效果可以用在angular的页面切换中, 所以将这个效果移植到angular中, 做 ...
- css图片映射
a <div class="imagemap"> <img src="img/map.png" width="496px" ...
- NVelocity 实现简单的留言板
留言版简单实现 -------------------------------------------------------------------------------------------- ...
- 如何使用javascript书写递归函数
递归函数大家都应该比较熟吧?那么,如何在javascript中书写一个完美的递归函数呢?且听我娓娓道来. 递归函数 写的时候,查了一下维基百科对递归函数的定义,恕我愚钝,简直太深奥了!所以,我还是简单 ...
- Android 全屏相关操作
1.隐藏标题栏(titlebar) (1)在代码中隐藏标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE); (2)在Manifest中Applicati ...