python3 结束线程_Python3使用线程

Python2标准库中提供了两个模块thread和threading支持多线程。

thread有一些缺陷在Python3中弃用,为了兼容性,python3 将 thread 重命名为 "_thread",在Python3中推荐直接使用threading。

创建线程对象

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

参数说明:

group 应该为 None;为了日后扩展 ThreadGroup 类实现而保留。

target 是用于 run() 方法调用的可调用对象。默认是 None,表示不需要调用任何方法。

name 是线程名称。默认情况下,由"Thread-N"格式构成一个唯一的名称,其中 N 是小的十进制数。

args 是用于调用目标函数的参数元组。默认是 ()。

kwargs 是用于调用目标函数的关键字参数字典。默认是 {}。

如果 daemon 不是 None,线程将被显式的设置为 守护模式,不管该线程是否是守护模式。如果是 None (默认值),线程将继承当前线程的守护模式属性。

线程对象其中的几个方法

start()开始线程活动。

run() 代表线程活动的方法。

join(timeout=None) 等待,直到线程终结

setDaemon()设置是否为守护线程

一、使用线程有两种方式:函数或者用类来包装线程对象

例子1:使用函数

importrandomimportthreadingimporttimedefrun(threadName):for i in range(5):

time.sleep(random.random())#这里只是演示参数,获取当前线程名可用threading.currentThread().getName()

print('{} : {}'.format(threadName, i))

t1= threading.Thread(target=run, args=('thread 1',))

t1.start()

t2= threading.Thread(target=run, args=('thread 2',))

t2.start()'''运行结果:

thread 2 : 0

thread 2 : 1

thread 1 : 0

thread 1 : 1

thread 2 : 2

thread 2 : 3

thread 1 : 2

thread 1 : 3

thread 2 : 4

thread 1 : 4'''

例子2:使用类(运行结果和例子1类似)

importrandomimportthreadingimporttimeclasstest(threading.Thread):def __init__(self,name):

super().__init__()

self.name=namedefrun(self):for i in range(5):

time.sleep(random.random())print('{} : {}'.format(self.name, i))

t1= test('thread 1')

t1.start()

t2= test('thread 2')

t2.start()

二、join(timeout=None) 方法

一个进程启动之后,会默认产生一个主线程A,当创建子线程B后,如果不调用B.join(),则主线程A和子线程B会同时执行;

如果调用B.join()则主线程会在调用处等待子线程B执行完后,才继续往下执行。

参数timeout是可选的,代表线程运行的最大时间,如果超过这个时间,不管这个线程有没有执行完毕都会被回收,然后主线程会接着执行。

join在start后才调用。

1、不调用子线程join方法

importrandomimportthreadingimporttimedefrun():

name=threading.currentThread().getName()print('{} start'.format(name))

time.sleep(random.random())print('{} end'.format(name))

threads=[]for i in range(5):

threads.append(threading.Thread(target=run))for th inthreads:

th.start()print("finished")'''运行结果

Thread-1 start

Thread-2 start

Thread-3 start

Thread-4 start

Thread-5 startfinished

Thread-5 end

Thread-3 end

Thread-2 end

Thread-4 end

Thread-1 end'''

2、调用子线程join方法

importrandomimportthreadingimporttimedefrun():

name=threading.currentThread().getName()print('{} start'.format(name))

time.sleep(random.random())print('{} end'.format(name))

threads=[]for i in range(5):

threads.append(threading.Thread(target=run))for th inthreads:

th.start()#等待,直到线程终结。

for th inthreads:

th.join()print("finished")'''运行结果

Thread-1 start

Thread-2 start

Thread-3 start

Thread-4 start

Thread-5 start

Thread-3 end

Thread-5 end

Thread-4 end

Thread-1 end

Thread-2 end

finished'''

三、setDaemon()方法

主线程A中创建子线程B后,如果调用B.setDaemon(),把子线程设置为守护线程。

表示主线程A一旦执行结束,不管子线程B是否执行完成,会全部被终止。

setDaemon和join相反,在start之前设置。

备注:

主线程在其它非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将会被回收,而进程必须保证非守护线程都运行完毕后才能结束。

所以如果存在多个子线程,假设有守护线程B,又有非守护线程C,则主线程会等待非守护线程C执行完,守护线程B如果还没执行完则会被终止。

importthreadingimporttimedefrun():

name=threading.currentThread().getName()print('{} start'.format(name))

time.sleep(2)#下面这行代码因为主线程已经执行结束,被终止执行

print('{} end'.format(name))print("start")

t= threading.Thread(target=run)

t.setDaemon(True)

t.start()

time.sleep(1)print("finished")'''运行结果

start

Thread-1 start

finished'''

四、线程锁

每个线程互相独立,相互之间没有任何关系,但是在同一个进程中的资源,线程是共享的,如果不进行资源的合理分配,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。

下面例子,如果不用线程锁Lock,则每次得到的结果都不一样。

from threading importThread, Lock

lock=Lock()

total=0#如果不使用lock那么,最后得到的数字不一定为0;

defcal(type):globaltotalfor i in range(1000000):

lock.acquire()if(type == '+'):

total+= 1

else:

total-= 1lock.release()

thread1= Thread(target=cal,args=('+',))

thread2= Thread(target=cal,args=('-',))

thread1.start()

thread2.start()

thread1.join()

thread2.join()print(total)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值