python守护线程和非守护线程_Python多线程01之------Python多线程就这么简单(重点:守护线程和普通线程的区别?和threading模块的用法。)...

@主要模块:thread模块,time模块

---模块函数:start_new_thread(func,args),allocate_lock(),exit。

锁对象有三个方法acquire(),locked(),release()。下面是如何生成锁对象:

---thread.allocate_lock()      生成锁对象,注意锁对象和线程是两个完全不同的概念

lock.acquire()    加锁,加锁后,线程就可以使用锁对象了

lock.release()    线程调度释放锁对象

---acquire负责加锁,release负责解锁。

如果锁定了,lock.locked()的状态为true,如果解锁了lock.locked()就是false

---一个使用案例:

ximAeC9yAEAAAAAAAAAAAAAEMCFkgDwWv8CgyV9CuG5qr4AAAAASUVORK5CYII=

上边代码中,首先声明一个播放视频函数(playVideo),下边声明一个锁对象,加锁。

下边声明两个新的线程,一个播放图片,播放30次,一个播放声音,播放30次。两个线程都上了锁。

当两者循环完以后,锁对象就会解锁l.release() ,lock.locked()状态就会变成false,就会退出循环。

1,什么是单线程?(一个时间点只能做一件事。)

在好些年前的MS-DOS时代,操作系统处理问题都是单任务的,我想做听音乐和看电影两件事儿,那么一定要先排一下顺序。

(好吧!我们不纠结在DOS时代是否有听音乐和看影的应用。^_^)

from time importctime,sleepdefmusic():for i in range(2):print "I was listening to music. %s" %ctime()

sleep(1)defmove():for i in range(2):print "I was at the movies! %s" %ctime()

sleep(5)if __name__ == '__main__':

music()

move()print "all over %s" %ctime()

我们先听了一首音乐,通过for循环来控制音乐的播放了两次,每首音乐播放需要1秒钟,sleep()来控制音乐播放的时长。接着我们又看了一场电影,每一场电影需要5秒钟,因为太好看了,所以我也通过for循环看两遍。在整个休闲娱乐活动结束后,我看了一下当前时间,差不多该睡觉了。

运行结果:

>>=========================== RESTART ================================

>>>I was listening to music. Thu Apr17 10:47:08 2014I was listening to music. Thu Apr17 10:47:09 2014I was at the movies! Thu Apr17 10:47:10 2014I was at the movies! Thu Apr17 10:47:15 2014all over Thu Apr17 10:47:20 2014

2,什么是多线程?同时做多件事情,例如同时执行多个方法。(@注意thread和threading用法是不同的?下边案例用的是threading方法)

科技在发展,时代在进步,我们的CPU也越来越快,CPU抱怨,P大点事儿占了我一定的时间,其实我同时干多个活都没问题的;于是,操作系统就进入了多任务时代。我们听着音乐玩着其他程序不在是梦想。

python提供了两个模块来实现多线程thread和threading ,thread 有一些缺点,在threading 得到了弥补,为了不浪费你和时间,所以我们直接学习threading 就可以了。

---threading模块建立在thread模块之上,可以更容易地管理多个执行线程。通过使用线程,程序可以在同一个进程空间并发地运行多个操作。threading模块建立在thread的底层特性基础之上,可以更容易地完成线程处理。

(1),第一个简单的实例

import threading

def worker(num):

print 'worker:%s' %num

return

threads=[]

for i in range(5):

t=threading.Thread(target=worker, args=(i, ))  //任何类型的对象,都可以作为参数传递到线程。联系C#中的多线程一起记忆

threads.append(t)

t.start()

---输出5行

worker:0

worker:1

worker:2

worker:3

worker:4

(2),确定当前线程

使用参数来标识或命名线程很麻烦,也没有必要。每个Thread实例都有一个名称,它有一个默认值,可以在创建线程时改变。如果服务器进程由处理不同操作的多个服务线程构成,在这样的服务器进程中,对线程命名很有用。

print threading.currentThread().getName()  //这段代码就能获取当前线程名,例如在上边worker方法中,加入这段代码,会输出Thread-5类似的线程名。

print threading.currentThread().getName(), num  //这后面可以加上参数,就会输出Thread-1 0

print threading.currentThread().getName(), 'starting'  //后面可以加上字符串,就会输出Thread-1 starting

(3),守护和非守护线程(守护线程的作用就是用一种容易的方法来中断线程!!!,具体用法,视情况而定。)

---在Java中也有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)

守护线程的概念有点不同于Linux环境下的概念,可能是我没理解,但是这个概念和Java里的守护线程一样:

守护线程在主线程退出后也会随着退出,非守护线程(普通线程)则不会。什么意思呢?看下边:

* 对于普通线程,如果线程的任务没有结束,主线程不会退出,整个程序也不会退出(程序会被无限挂起);

* 对于守护线程,即使线程任务还没有结束,如果主线程退出该线程也会退出;

*守护线程作用:如果一个服务无法用一种容易的方法来中断线程,或者希望线程工作到一半时中止而不损失或破坏数据,对于这些服务,使用守护线程就很有用。要标志一个线程为守护线程,需要调用其setDaemon()放法并提供参数True。

---默认情况下线程不是守护线程。

* 实例如下:

#coding=utf8

import threading

import time

import logging

logging.basicConfig(level=logging.DEBUG, format='(%(threadName)-10s %(message)s', )

def daemon():

logging.debug('Starting')

time.sleep(2)

logging.debug('Exiting')

#这个函数执行线程,设置为守护线程以后,这里就不会再输出Exiting。因为在守护线程从其2秒的睡眠时间唤醒之前,所有非守护线程(包括主线程)已经退出。

#主线程退出后,守护线程也会退出,所以上边不会输出Exiting。

#(对于守护线程,即使线程任务还没有结束,如果主线程退出该线程也会退出;)

d=threading.Thread(name='daemon', target=daemon)

d.setDaemon(True)  #如果这里注释掉,程序执行时,就会停顿2秒,输出Exiting。(为什么?因为对于普通线程,如果线程的任务没有结束,主线程不会退出,整个程序也不会退出;)

def non_daemon():

logging.debug('Starting')

logging.debug('Exiting')

t=threading.Thread(name='non-daemon', target=non_daemon)

d.start()

t.start()

* 要等待一个守护线程完成工作,需要使用join()方法。(join的作用:即使主线程退出,守护线程的任务没有结束,守护线程也不退出。)

1),在上边代码的最后加上如下代码:

d.join()

t.join()

使用join()等待守护线程退出,这意味着它就会输出"Exiting"消息。加了join以后,守护线程等于变成了普通线程了。

(daemon     Starting

(non-daemon Starting

(non-daemon Exiting

(daemon     Exiting

2),默认情况下,join()会无限阻塞。还可以传入一个浮点数值,表示等待线程变为不活动所需的时间(秒数)。即使线程在这个时间段内未完成,join()也会返回。

d.join(1)

print 'd.isAlive()',d.isAlive() //用isAlive()方法判断线程是否活动,true表示活动--存活,false表示不活动--中断,不存活。

t.join()

time.sleep(3)  //如果不加下边三行代码,就不会输出(daemon     )Exiting,守护线程会随主线程的退出而退出

print d.isAlive()

print t.isAlive()

由于传入的超时时间小于守护线程睡眠的时间,所以join()返回之后这个线程扔'存活'。在上面代码中,守护线程设置睡眠2秒(time.sleep(2)),上边,我们设置time.sleep(3),延长主线程退出时间,所以下边(daemon     )Exiting依然会输出。输出所有后,两个线程的状态都是False(中断)。

BzuQy951lEmCAAAAAElFTkSuQmCC

(daemon     ) Exiting

False

False

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值