python threading_Python之threading模块的使用

作用:同一个进程空间并发运行多个操作,专业术语简称为:【多线程】

1、任务函数不带参数多线程

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingdefworker():print('worker...')

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

task= threading.Thread(target=worker)

threads.append(task)

task.start()print(threads)

threading_simple.py

运行效果

[root@ mnt]# python3 threading_simple.py

worker...

worker...

worker...

[, , ]

2、任务函数带参数多线程

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingdefworker(num):print('worker %s...' %num)

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

task= threading.Thread(target=worker, args=(i,))

threads.append(task)

task.start()print(threads)

threading_simple_args.py

运行效果

[root@ mnt]# python3 threading_simple_args.py

worker0...

worker1...

worker2...

[, , ]

3、线程标识名字设置和获取

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimedefworker():print(threading.current_thread().getName(), 'Starting')

time.sleep(0.2)print(threading.current_thread().getName(), 'Exiting')defmy_service():print(threading.current_thread().getName(), 'Starting')

time.sleep(0.3)print(threading.current_thread().getName(), 'Exiting')

my_service_task= threading.Thread(name='my_service', target=my_service)

worker_task= threading.Thread(name='worker', target=worker)

default_task= threading.Thread(target=worker) #使用默认的名字Thread-1

my_service_task.start()

worker_task.start()

default_task.start()

threading_name.py

运行效果

[root@ mnt]# python3 threading_name.py

my_service Starting

worker Starting

Thread-1Starting

worker Exiting

Thread-1Exiting

my_service Exiting

4、线程标识名字设置和获取,利用logging模块打印出来日志,调试一般不建议用print打印出来

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimeimportloggingdefworker():

logging.debug('Starting')

time.sleep(0.2)

logging.debug('Exiting')defmy_service():

logging.debug('Starting')

time.sleep(0.3)

logging.debug('Exiting')

logging.basicConfig(

level=logging.DEBUG,#以下格式化,参考官方文档:https://docs.python.org/3/library/logging.html

format='[%(levelname)s] (%(thread)d) (%(threadName)-10s) %(message)s',

)

my_service_task= threading.Thread(name='my_service', target=my_service)

worker_task= threading.Thread(name='worker', target=worker)

default_task= threading.Thread(target=worker) #使用默认的名字Thread-1

my_service_task.start()

worker_task.start()

default_task.start()

threading_name_logging.py

运行效果

[root@ mnt]# python3 threading_name_logging.py

[DEBUG] (140555433457408) (my_service) Starting

[DEBUG] (140555354896128) (worker ) Starting

[DEBUG] (140555346503424) (Thread-1) Starting

[DEBUG] (140555354896128) (worker ) Exiting

[DEBUG] (140555346503424) (Thread-1) Exiting

[DEBUG] (140555433457408) (my_service) Exiting

5、守护线程随着主程序退出而关闭线程

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimeimportloggingdefdaemon():

logging.debug('daemon Starting...')

time.sleep(0.2)

logging.debug('daemon Exiting...')defnon_daemon():

logging.debug('non_daemon Starting...')

logging.debug('non_daemon Exiting...')

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s')

daemon_task= threading.Thread(name='daemon', target=daemon, daemon=True) #设置为首护线程

non_daemon_task = threading.Thread(name='non_daemon_task', target=non_daemon)

daemon_task.start()

non_daemon_task.start()

threading_daemon.py

运行效果

[root@mnt]#python3 threading_daemon.py

(daemon ) daemon Starting...

(non_daemon_task) non_daemon Starting...

(non_daemon_task) non_daemon Exiting...#由于守护线程还没有执行完,主进程已退出,守护线程即随之被终止,从而导致【daemon Exiting...】没打印出来

6、等待守护线程运行结束,才关闭主程序

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimeimportloggingdefdaemon():

logging.debug('daemon Starting...')

time.sleep(0.2)

logging.debug('daemon Exiting...')defnon_daemon():

logging.debug('non_daemon Starting...')

logging.debug('non_daemon Exiting...')

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s')

daemon_task= threading.Thread(name='daemon', target=daemon, daemon=True) #设置为首护线程

non_daemon_task = threading.Thread(name='non_daemon_task', target=non_daemon)

daemon_task.start()

non_daemon_task.start()

daemon_task.join()

non_daemon_task.join()

threading_daemon_join

运行效果

[root@ mnt]# python3 threading_daemon_join.py

(daemon ) daemon Starting...

(non_daemon_task) non_daemon Starting...

(non_daemon_task) non_daemon Exiting...

(daemon ) daemon Exiting...

#由于使用的join等待线程运行完成,才结束,所以【daemon Exiting...】可以打印出来

7、设置守护线程的超时时间,防止进入无限阻塞

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimeimportloggingdefdaemon():

logging.debug('daemon Starting...')

time.sleep(0.2)

logging.debug('daemon Exiting...')defnon_daemon():

logging.debug('non_daemon Starting...')

logging.debug('non_daemon Exiting...')

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s')

daemon_task= threading.Thread(name='daemon', target=daemon, daemon=True) #设置为首护线程

non_daemon_task = threading.Thread(name='non_daemon_task', target=non_daemon)

daemon_task.start()

non_daemon_task.start()

daemon_task.join(0.1) #设置的超时时间0.1秒,因为该任务的函数睡眠0.2s,所以没有运行完成,就已经超时,结束该守护线程

print('isAlive()', daemon_task.isAlive())

non_daemon_task.join()

threading_daemon_join_timeout.py

运行效果

[root@ mnt]# python3 threading_daemon_join_timeout.py

(daemon ) daemon Starting...

(non_daemon_task) non_daemon Starting...

(non_daemon_task) non_daemon Exiting...

isAlive() True #这里是判断线程是否在运行,True表在线程还在运行

8、利用threading.enumerate()枚举的方法,设置守护线程等待运行完成

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimporttimeimportloggingimportrandomdefworker():

pause= random.randint(1, 5) / 10logging.debug('睡眠 %0.2f 秒', pause)

time.sleep(pause)

logging.debug('worker 结束')

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s')for i in range(3):

task= threading.Thread(target=worker, daemon=True)

task.start()

main_thread=threading.main_thread()for task_obj in threading.enumerate(): #threading.enumerate():返回当前运行守护线程的实例

if task_obj ismain_thread:continuelogging.debug('等待 %s', task_obj.getName())

task_obj.join()

threading_enumerate.py

运行效果

[root@ mnt]# python3 threading_enumerate.py

(Thread-1 ) 睡眠 0.30秒

(Thread-2 ) 睡眠 0.10秒

(Thread-3 ) 睡眠 0.10秒

(MainThread) 等待 Thread-1(Thread-2) worker 结束

(Thread-3) worker 结束

(Thread-1) worker 结束

(MainThread) 等待 Thread-2(MainThread) 等待 Thread-3

9、利用继承threading.Thread类,实现无参的多线程

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingclassMyThread(threading.Thread):defrun(self):

logging.debug('运行...')

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)for i in range(5):

task=MyThread()

task.start()

threading_subclass.py

运行效果

[root@ mnt]#

[root@python-mysql mnt]# python3 threading_subclass.py

(Thread-1) 运行...

(Thread-2) 运行...

(Thread-3) 运行...

(Thread-4) 运行...

(Thread-5 ) 运行...

10、利用继承threading.Thread类,实现有参的多线程

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingclassMyThread(threading.Thread):def __init__(self, group=None, target=None, name=None, daemon=None, args=(), kwargs=None):

super(MyThread, self).__init__(group=group, target=target, name=name, daemon=daemon)

self.args=args

self.kwargs=kwargsdefrun(self):

logging.debug('运行...args : %s,kwargs : %s', self.args, self.kwargs)

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)for i in range(5):

task= MyThread(args=(i,), kwargs={'a': 'A', 'b': 'B'})

task.start()

threading_subclass_args.py

运行效果

[root@ mnt]# python3 threading_subclass_args.py

(Thread-1 ) 运行...args : (0,),kwargs : {'a': 'A', 'b': 'B'}

(Thread-2 ) 运行...args : (1,),kwargs : {'a': 'A', 'b': 'B'}

(Thread-3 ) 运行...args : (2,),kwargs : {'a': 'A', 'b': 'B'}

(Thread-4 ) 运行...args : (3,),kwargs : {'a': 'A', 'b': 'B'}

(Thread-5 ) 运行...args : (4,),kwargs : {'a': 'A', 'b': 'B'}

11、定时器线程threading.Timer

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedefdelayed():

logging.debug('delayed运行...')

logging.basicConfig(

level=logging.DEBUG,

format="(%(threadName)-10s) %(message)s")

task_1= threading.Timer(0.3, delayed)

task_1.setName('task_1')

task_2= threading.Timer(0.3, delayed)

task_2.setName('task_2')

logging.debug('开始运行Timer')

task_1.start()

task_2.start()

logging.debug('取消前等待')

time.sleep(0.2)

logging.debug('取消 %s' %task_2.getName())

task_2.cancel()

logging.debug('取消完成')

threading_timer.py

运行效果

[root@ mnt]# python3 threading_timer.py

(MainThread) 开始运行Timer

(MainThread) 取消前等待

(MainThread) 取消 task_2

(MainThread) 取消完成

(task_1 ) delayed运行...

#task_2已经被取消,所以没有运行

12、线程间信号相互传送threading.Event

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedefwait_for_event(event_obj):

logging.debug('等待事件的开始')

event_is_set=event_obj.wait()

logging.debug('事件设置 %s' %event_is_set)defwait_for_event_timeout(event_obj, timeout):while notevent_obj.is_set():

logging.debug('等待事件超时开始')

event_is_set=event_obj.wait(timeout)ifevent_is_set:

logging.debug('处理事件')else:

logging.debug('做其他工作')

logging.basicConfig(

level=logging.DEBUG,

format="(%(threadName)-10s) %(message)s")

event_obj=threading.Event()

task_1=threading.Thread(

name='block',

target=wait_for_event,

args=(event_obj,)

)

task_1.start()

task_2=threading.Thread(

name='nonblock',

target=wait_for_event_timeout,

args=(event_obj, 2)

)

task_2.start()

logging.debug('在呼叫前等待 Event.set()')

time.sleep(0.3)

event_obj.set()

logging.debug('事件已经设置')

threading_event.py

运行效果

[root@ mnt]# python3 threading_event.py

(block ) 等待事件的开始

(nonblock ) 等待事件超时开始

(MainThread) 在呼叫前等待 Event.set()

(MainThread) 事件已经设置

(block ) 事件设置 True

(nonblock ) 处理事件

13、控制资源访问_计数器_多线程加阻塞锁的示例

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimeimportrandomclassCounter(object):def __init__(self, start=0):

self.lock=threading.Lock()

self.value=startdefincrement(self):

logging.debug('等待锁')

self.lock.acquire()try:

logging.debug('获取锁')

self.value+= 1

finally:

self.lock.release()defworker(c):for i in range(2):

pause=random.random()

logging.debug('睡眠 %0.02f', pause)

time.sleep(pause)

c.increment()

logging.debug('worker运行结束')

logging.basicConfig(

level=logging.DEBUG,

format="(%(threadName)-10s) %(message)s")

counter=Counter()for i in range(2):

t= threading.Thread(target=worker, args=(counter,))

t.start()

logging.debug('等待线程worker运行结束')

main_thread=threading.main_thread()for t inthreading.enumerate():if t is notmain_thread:

t.join()

logging.debug('Counter: %d', counter.value)

threading_lock.py

运行效果

[root@mnt]# python3 threading_lock.py

(Thread-1 ) 睡眠 0.36(Thread-2 ) 睡眠 0.77(MainThread) 等待线程worker运行结束

(Thread-1) 等待锁

(Thread-1) 获取锁

(Thread-1 ) 睡眠 0.43(Thread-2) 等待锁

(Thread-2) 获取锁

(Thread-2 ) 睡眠 0.12(Thread-1) 等待锁

(Thread-1) 获取锁

(Thread-1) worker运行结束

(Thread-2) 等待锁

(Thread-2) 获取锁

(Thread-2) worker运行结束

(MainThread) Counter:4 #运行4次,所以显示4

14、控制资源访问_计数器_多线程非阻塞锁的示例

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedeflock_holder(lock_obj):

logging.debug('lock_holder 开始')whileTrue:

lock_obj.acquire()try:

logging.debug('Holding')

time.sleep(0.5)finally:

logging.debug('Not Holding')

lock_obj.release()

time.sleep(0.5)defworker(lock_obj):

logging.debug('worker 开始')

num_tries=0

num_acquires=0while num_acquires < 3:

time.sleep(0.5)

logging.debug('尝试获取锁')

have_it= lock_obj.acquire(0) #主要核心代码在这里,不断尝试获取锁,通过这个判断锁是否释放可以获取

try:

num_tries+= 1

ifhave_it:

logging.debug('重试次数 %d: 得到锁', num_tries)

num_acquires+= 1

else:

logging.debug('重试次数 %d: 没有得到锁', num_tries)finally:ifhave_it:

lock_obj.release()

logging.debug('获取锁一共尝试的 %d 次', num_tries)

logging.basicConfig(

level=logging.DEBUG,

format="(%(threadName)-10s) %(message)s")

lock=threading.Lock()

holder=threading.Thread(

target=lock_holder,

args=(lock,),

name='LockHolder',

daemon=True,

)

holder.start()

worker=threading.Thread(

target=worker,

args=(lock,),

name='Worker',

)

worker.start()

threading_lock_nonblock.py

运行结果

[root@ mnt]# python3 threading_lock_nonblock.py

(LockHolder) lock_holder 开始

(LockHolder) Holding

(Worker ) worker 开始

(LockHolder) Not Holding

(Worker ) 尝试获取锁

(Worker ) 重试次数1: 得到锁

(LockHolder) Holding

(Worker ) 尝试获取锁

(Worker ) 重试次数2: 没有得到锁

(LockHolder) Not Holding

(Worker ) 尝试获取锁

(Worker ) 重试次数3: 得到锁

(LockHolder) Holding

(Worker ) 尝试获取锁

(Worker ) 重试次数4: 没有得到锁

(LockHolder) Not Holding

(Worker ) 尝试获取锁

(Worker ) 重试次数5: 得到锁

(Worker ) 获取锁一共尝试的5次

#尝试的次数是随机,这样子的好处,不会因为阻塞占有CPU资源

15、互斥锁

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreading

lock=threading.Lock()print('第一个锁', lock.acquire())print('第二个锁', lock.acquire(0))

threading_lock_reacquire.py

运行效果

[root@ mnt]#python3 threading_lock_reacquire.py

第一个锁 True

第二个锁 False

16、同步锁

ContractedBlock.gif

ExpandedBlockStart.gif

importthreading

lock=threading.RLock()print('第一个锁', lock.acquire())print('第二个锁', lock.acquire(0))

threading_rlock.py

运行效果

[root@ mnt]# python3 threading_rlock.py

第一个锁 True

第二个锁 True

17、利用with管理锁,无需每次都释放锁lock.release()

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingdefworker_with(lock):

with lock:

logging.debug('当前运行是用with 获取锁')defworker_no_with(lock):

lock.acquire()try:

logging.debug('当前运行是用 lock.acquire() 获取锁')finally:

lock.release()

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

lock=threading.Lock()

with_open_lock= threading.Thread(target=worker_with, args=(lock,))

no_with_open_lock= threading.Thread(target=worker_no_with, args=(lock,))

with_open_lock.start()

no_with_open_lock.start()

threading_lock_with.py

运行效果

[root@ mnt]# python3 threading_with_lock.py

(Thread-1) 当前运行是用with 获取锁

(Thread-2 ) 当前运行是用 lock.acquire() 获取锁

18、利用threading.Condition(),实现线程同步,下面是生产者和消费者的示例

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedefconsumer(condition_obj):"""消费者"""logging.debug('消费者线程开启')

with condition_obj:

condition_obj.wait()

logging.debug('资源可供消费者使用。')defproducer(condition_obj):"""生产者"""logging.debug('生产者线程开启')

with condition_obj:

logging.debug('生产可用资源')

condition_obj.notifyAll()

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

condition_obj=threading.Condition()#消费者实例1

c1 =threading.Thread(

name='c1',

target=consumer,

args=(condition_obj,)

)#消费者实例1

c2 =threading.Thread(

name='c2',

target=consumer,

args=(condition_obj,)

)#生产者实例

p =threading.Thread(

name='p',

target=producer,

args=(condition_obj,)

)

c1.start()

time.sleep(0.2)

c2.start()

time.sleep(0.2)

p.start()

threading_condition.py

运行效果

[root@ mnt]# python3 threading_condition.py

(c1 ) 消费者线程开启

(c2 ) 消费者线程开启

(p ) 生产者线程开启

(p ) 生产可用资源

(c1 ) 资源可供消费者使用。

(c2 ) 资源可供消费者使用。

19、线程同步threading.Barrier() ,作用:等待所有线程一起开启后,再全部一起执行主要的功能

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedefworker(barrier):

logging.debug('当前线程名字: %s 与 %s 其他人一起等待后面的功能' %(threading.current_thread().name, barrier.n_waiting))

worker_id=barrier.wait()

logging.debug('%s 已经等待完毕 %s' %(threading.current_thread().name, worker_id))

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

NUM_THREADS= 3barrier=threading.Barrier(NUM_THREADS)

threads=[

threading.Thread(

name='worker-%s' %i,

target=worker,

args=(barrier,)

)for i inrange(NUM_THREADS)

]#这里是实例化3个线程,[, , ]

for thread_obj inthreads:

logging.debug('%s 开启' %thread_obj.name)

thread_obj.start()

time.sleep(0.2)for thread_obj inthreads:

thread_obj.join()

threading_barrier.py

运行效果

[root@ mnt]# python3 threading_barrier.py

(MainThread) worker-0开启

(worker-0 ) 当前线程名字: worker-0 与 0其他人一起等待后面的功能

(MainThread) worker-1开启

(worker-1 ) 当前线程名字: worker-1 与 1其他人一起等待后面的功能

(MainThread) worker-2开启

(worker-2 ) 当前线程名字: worker-2 与 2其他人一起等待后面的功能

(worker-2 ) worker-2 已经等待完毕 2(worker-0 ) worker-0 已经等待完毕 0(worker-1 ) worker-1 已经等待完毕 1

20、线程同步barrier.abort()中断的操作,作用:等待所有线程运行后面的功能,然后对它进行中断的操作,使用停止运行

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimedefworker(barrier):

logging.debug('当前线程名字: %s 与 %s 其他人一起等待后面的功能' %(threading.current_thread().name, barrier.n_waiting))try:

worker_id=barrier.wait()exceptthreading.BrokenBarrierError:

logging.debug('%s 中断', threading.current_thread().name)else:

logging.debug('%s 已经等待完毕 %s' %(threading.current_thread().name, worker_id))

logging.basicConfig(

level=logging.DEBUG,

format='(%(threadName)-10s) %(message)s',

)

NUM_THREADS= 3

#barrier.abort()必须多加一个线程,所以这里需要加1

barrier = threading.Barrier(NUM_THREADS + 1)

threads=[

threading.Thread(

name='worker-%s' %i,

target=worker,

args=(barrier,)

)for i inrange(NUM_THREADS)

]#这里是实例化3个线程,[, , ]

for thread_obj inthreads:

logging.debug('%s 开启' %thread_obj.name)

thread_obj.start()

time.sleep(0.1)#中断线程一起同步运行

barrier.abort()for thread_obj inthreads:

thread_obj.join()

threading_barrier_abort.py

运行效果

[root@ mnt]# python3 threading_barrier_abort.py

(MainThread) worker-0开启

(worker-0 ) 当前线程名字: worker-0 与 0其他人一起等待后面的功能

(MainThread) worker-1开启

(worker-1 ) 当前线程名字: worker-1 与 1其他人一起等待后面的功能

(MainThread) worker-2开启

(worker-2 ) 当前线程名字: worker-2 与 2其他人一起等待后面的功能

(worker-0 ) worker-0中断

(worker-1 ) worker-1中断

(worker-2 ) worker-2 中断

21、threading.Semaphore(),自定义线程池

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importthreadingimportloggingimporttimeclassActivePool(object):"""活动池"""

def __init__(self):

self.active=[]

self.lock=threading.Lock()defmakeActive(self, name):"""获取一个锁,把活动的名字增加于列表中"""with self.lock:

self.active.append(name)

logging.debug('运行:%s' %self.active)defmakeInactive(self, name):

with self.lock:

self.active.remove(name)

logging.debug('运行:%s', self.active)defworker(semaphore_obj, pool):

logging.debug('正在等待加入池')

with semaphore_obj:

name=threading.current_thread().getName()

pool.makeActive(name)

time.sleep(0.1)

pool.makeInactive(name)

logging.basicConfig(

level=logging.DEBUG,

format='%(asctime)s (%(threadName)-10s) %(message)s',

)

pool=ActivePool()

semaphore_obj= threading.Semaphore(2)for i in range(4):

t=threading.Thread(

target=worker,

name=str(i),

args=(semaphore_obj, pool)

)

t.start()

threading_semaphore.py

运行效果

[root@ mnt]# python3 threading_semaphore.py2019-12-08 15:31:47,387 (0) 正在等待加入池2019-12-08 15:31:47,387 (0 ) 运行:['0']2019-12-08 15:31:47,388 (1) 正在等待加入池2019-12-08 15:31:47,389 (1 ) 运行:['0', '1']2019-12-08 15:31:47,389 (2) 正在等待加入池2019-12-08 15:31:47,390 (3) 正在等待加入池2019-12-08 15:31:47,489 (0 ) 运行:['1']2019-12-08 15:31:47,491 (1) 运行:[]2019-12-08 15:31:47,492 (2 ) 运行:['2']2019-12-08 15:31:47,494 (3 ) 运行:['2', '3']2019-12-08 15:31:47,593 (2 ) 运行:['3']2019-12-08 15:31:47,596 (3 ) 运行:[]

22、threading.local(),本地线程任务运行隔离

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importrandomimportthreadingimportloggingdefshow_value(local_obj):try:

val=local_obj.valueexceptAttributeError:

logging.debug('值不存在')else:

logging.debug('value=%s', val)defworker(local_obj):

show_value(local_obj)

local_obj.value= random.randint(1, 100)

show_value(local_obj)

logging.basicConfig(

level=logging.DEBUG,

format='%(asctime)s (%(threadName)-10s) %(message)s',

)

local_obj=threading.local()#第一次运行没有设置value值,会报AttributeError异常

show_value(local_obj)#第二次运行有设置value值,所以会显示出值

local_obj.value = 1000show_value(local_obj)for i in range(2):

t=threading.Thread(

target=worker,

args=(local_obj,),

)

t.start()

threading_local.py

运行效果

[root@ mnt]# python3 threading_local.py2019-12-08 16:23:17,696(MainThread) 值不存在2019-12-08 16:23:17,697 (MainThread) value=1000

2019-12-08 16:23:17,697 (Thread-1) 值不存在2019-12-08 16:23:17,698 (Thread-1 ) value=26

2019-12-08 16:23:17,698 (Thread-2) 值不存在2019-12-08 16:23:17,698 (Thread-2 ) value=39

23、threading.local(),本地线程任务运行隔离,初始化全局变量值

ContractedBlock.gif

ExpandedBlockStart.gif

#!/usr/bin/env python#-*- coding: utf-8 -*-

importrandomimportthreadingimportloggingdefshow_value(local_obj):try:

val=local_obj.valueexceptAttributeError:

logging.debug('值不存在')else:

logging.debug('value=%s', val)defworker(local_obj):

show_value(local_obj)

local_obj.value= random.randint(1, 100)

show_value(local_obj)

logging.basicConfig(

level=logging.DEBUG,

format='%(asctime)s (%(threadName)-10s) %(message)s',

)classMyLocal(threading.local):def __init__(self, value, *args, **kwargs):

super(MyLocal, self).__init__(*args, **kwargs)

logging.debug('初始化值 %r', self)

self.value=value

local_obj= MyLocal(1000)

show_value(local_obj)for i in range(2):

t=threading.Thread(

target=worker,

args=(local_obj,)

)

t.start()

threading_local.default.py

测试效果

[root@ mnt]# python3 threading_local.default.py2019-12-08 16:28:48,168 (MainThread) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>

2019-12-08 16:28:48,168 (MainThread) value=1000

2019-12-08 16:28:48,169 (Thread-1 ) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>

2019-12-08 16:28:48,169 (Thread-1 ) value=1000

2019-12-08 16:28:48,169 (Thread-1 ) value=11

2019-12-08 16:28:48,170 (Thread-2 ) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>

2019-12-08 16:28:48,170 (Thread-2 ) value=1000

2019-12-08 16:28:48,170 (Thread-2 ) value=7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值