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

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading def worker():
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...
[<Thread(Thread-, stopped )>, <Thread(Thread-, stopped )>, <Thread(Thread-, stopped )>]

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading def worker(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
worker ...
worker ...
worker ...
[<Thread(Thread-, stopped )>, <Thread(Thread-, stopped )>, <Thread(Thread-, stopped )>]

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time def worker():
print(threading.current_thread().getName(), 'Starting')
time.sleep(0.2)
print(threading.current_thread().getName(), 'Exiting') def my_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- Starting
worker Exiting
Thread- Exiting
my_service Exiting

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time
import logging def worker():
logging.debug('Starting')
time.sleep(0.2)
logging.debug('Exiting') def my_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] () (my_service) Starting
[DEBUG] () (worker ) Starting
[DEBUG] () (Thread- ) Starting
[DEBUG] () (worker ) Exiting
[DEBUG] () (Thread- ) Exiting
[DEBUG] () (my_service) Exiting

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time
import logging def daemon():
logging.debug('daemon Starting...')
time.sleep(0.2)
logging.debug('daemon Exiting...') def non_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、等待守护线程运行结束,才关闭主程序

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time
import logging def daemon():
logging.debug('daemon Starting...')
time.sleep(0.2)
logging.debug('daemon Exiting...') def non_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、设置守护线程的超时时间,防止进入无限阻塞

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time
import logging def daemon():
logging.debug('daemon Starting...')
time.sleep(0.2)
logging.debug('daemon Exiting...') def non_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()枚举的方法,设置守护线程等待运行完成

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import time
import logging
import random def worker():
pause = random.randint(1, 5) / 10
logging.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 is main_thread:
continue
logging.debug('等待 %s', task_obj.getName())
task_obj.join()

threading_enumerate.py

运行效果

[root@ mnt]# python3 threading_enumerate.py
(Thread- ) 睡眠 0.30 秒
(Thread- ) 睡眠 0.10 秒
(Thread- ) 睡眠 0.10 秒
(MainThread) 等待 Thread-
(Thread- ) worker 结束
(Thread- ) worker 结束
(Thread- ) worker 结束
(MainThread) 等待 Thread-
(MainThread) 等待 Thread-

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging class MyThread(threading.Thread):
def run(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- ) 运行...
(Thread- ) 运行...
(Thread- ) 运行...
(Thread- ) 运行...
(Thread- ) 运行...

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging class MyThread(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 = kwargs def run(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- ) 运行...args : (,),kwargs : {'a': 'A', 'b': 'B'}
(Thread- ) 运行...args : (,),kwargs : {'a': 'A', 'b': 'B'}
(Thread- ) 运行...args : (,),kwargs : {'a': 'A', 'b': 'B'}
(Thread- ) 运行...args : (,),kwargs : {'a': 'A', 'b': 'B'}
(Thread- ) 运行...args : (,),kwargs : {'a': 'A', 'b': 'B'}

 11、定时器线程threading.Timer

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def delayed():
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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def wait_for_event(event_obj):
logging.debug('等待事件的开始')
event_is_set = event_obj.wait()
logging.debug('事件设置 %s' % event_is_set) def wait_for_event_timeout(event_obj, timeout):
while not event_obj.is_set():
logging.debug('等待事件超时开始')
event_is_set = event_obj.wait(timeout)
if event_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、控制资源访问_计数器_多线程加阻塞锁的示例

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time
import random class Counter(object):
def __init__(self, start=0):
self.lock = threading.Lock()
self.value = start def increment(self):
logging.debug('等待锁')
self.lock.acquire()
try:
logging.debug('获取锁')
self.value += 1
finally:
self.lock.release() def worker(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 in threading.enumerate():
if t is not main_thread:
t.join()
logging.debug('Counter: %d', counter.value)

threading_lock.py

运行效果

[root@mnt]# python3 threading_lock.py
(Thread- ) 睡眠 0.36
(Thread- ) 睡眠 0.77
(MainThread) 等待线程worker运行结束
(Thread- ) 等待锁
(Thread- ) 获取锁
(Thread- ) 睡眠 0.43
(Thread- ) 等待锁
(Thread- ) 获取锁
(Thread- ) 睡眠 0.12
(Thread- ) 等待锁
(Thread- ) 获取锁
(Thread- ) worker运行结束
(Thread- ) 等待锁
(Thread- ) 获取锁
(Thread- ) worker运行结束
(MainThread) Counter: #运行4次,所以显示4

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def lock_holder(lock_obj):
logging.debug('lock_holder 开始')
while True:
lock_obj.acquire()
try:
logging.debug('Holding')
time.sleep(0.5)
finally:
logging.debug('Not Holding')
lock_obj.release()
time.sleep(0.5) def worker(lock_obj):
logging.debug('worker 开始')
num_tries = 0
num_acquires = 0
while num_acquires < 3:
time.sleep(0.5)
logging.debug('尝试获取锁')
have_it = lock_obj.acquire(0) # 主要核心代码在这里,不断尝试获取锁,通过这个判断锁是否释放可以获取
try:
num_tries += 1
if have_it:
logging.debug('重试次数 %d: 得到锁', num_tries)
num_acquires += 1
else:
logging.debug('重试次数 %d: 没有得到锁', num_tries)
finally:
if have_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 ) 重试次数 : 得到锁
(LockHolder) Holding
(Worker ) 尝试获取锁
(Worker ) 重试次数 : 没有得到锁
(LockHolder) Not Holding
(Worker ) 尝试获取锁
(Worker ) 重试次数 : 得到锁
(LockHolder) Holding
(Worker ) 尝试获取锁
(Worker ) 重试次数 : 没有得到锁
(LockHolder) Not Holding
(Worker ) 尝试获取锁
(Worker ) 重试次数 : 得到锁
(Worker ) 获取锁一共尝试的 次
#尝试的次数是随机,这样子的好处,不会因为阻塞占有CPU资源

 15、互斥锁

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import threading lock = threading.Lock() print('第一个锁', lock.acquire())
print('第二个锁', lock.acquire(0))

threading_lock_reacquire.py

运行效果

[root@ mnt]# python3 threading_lock_reacquire.py
第一个锁 True
第二个锁 False

16、同步锁

import threading

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()

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging def worker_with(lock):
with lock:
logging.debug('当前运行是用with 获取锁') def worker_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- ) 当前运行是用with 获取锁
(Thread- ) 当前运行是用 lock.acquire() 获取锁

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def consumer(condition_obj):
"""消费者"""
logging.debug('消费者线程开启')
with condition_obj:
condition_obj.wait()
logging.debug('资源可供消费者使用。') def producer(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() ,作用:等待所有线程一起开启后,再全部一起执行主要的功能

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def worker(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 = 3 barrier = threading.Barrier(NUM_THREADS) threads = [
threading.Thread(
name='worker-%s' % i,
target=worker,
args=(barrier,)
) for i in range(NUM_THREADS)
] # 这里是实例化3个线程,[<Thread(worker-0, initial)>, <Thread(worker-1, initial)>, <Thread(worker-2, initial)>] for thread_obj in threads:
logging.debug('%s 开启' % thread_obj.name)
thread_obj.start()
time.sleep(0.2) for thread_obj in threads:
thread_obj.join()

threading_barrier.py

运行效果

[root@ mnt]# python3 threading_barrier.py
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(worker- ) worker- 已经等待完毕
(worker- ) worker- 已经等待完毕
(worker- ) worker- 已经等待完毕

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time def worker(barrier):
logging.debug('当前线程名字: %s 与 %s 其他人一起等待后面的功能' % (threading.current_thread().name, barrier.n_waiting))
try:
worker_id = barrier.wait()
except threading.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 in range(NUM_THREADS)
] # 这里是实例化3个线程,[<Thread(worker-0, initial)>, <Thread(worker-1, initial)>, <Thread(worker-2, initial)>] for thread_obj in threads:
logging.debug('%s 开启' % thread_obj.name)
thread_obj.start()
time.sleep(0.1) #中断线程一起同步运行
barrier.abort() for thread_obj in threads:
thread_obj.join()

threading_barrier_abort.py

运行效果

[root@ mnt]# python3 threading_barrier_abort.py
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(MainThread) worker- 开启
(worker- ) 当前线程名字: worker- 与 其他人一起等待后面的功能
(worker- ) worker- 中断
(worker- ) worker- 中断
(worker- ) worker- 中断

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import threading
import logging
import time class ActivePool(object):
"""活动池""" def __init__(self):
self.active = []
self.lock = threading.Lock() def makeActive(self, name):
"""获取一个锁,把活动的名字增加于列表中"""
with self.lock:
self.active.append(name)
logging.debug('运行:%s' % self.active) def makeInactive(self, name):
with self.lock:
self.active.remove(name)
logging.debug('运行:%s', self.active) def worker(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.py
-- ::, ( ) 正在等待加入池
-- ::, ( ) 运行:['']
-- ::, ( ) 正在等待加入池
-- ::, ( ) 运行:['', '']
-- ::, ( ) 正在等待加入池
-- ::, ( ) 正在等待加入池
-- ::, ( ) 运行:['']
-- ::, ( ) 运行:[]
-- ::, ( ) 运行:['']
-- ::, ( ) 运行:['', '']
-- ::, ( ) 运行:['']
-- ::, ( ) 运行:[]

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import random
import threading
import logging def show_value(local_obj):
try:
val = local_obj.value
except AttributeError:
logging.debug('值不存在')
else:
logging.debug('value=%s', val) def worker(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 = 1000
show_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.py
-- ::, (MainThread) 值不存在
-- ::, (MainThread) value=
-- ::, (Thread- ) 值不存在
-- ::, (Thread- ) value=
-- ::, (Thread- ) 值不存在
-- ::, (Thread- ) value=

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

#!/usr/bin/env python
# -*- coding: utf-8 -*- import random
import threading
import logging def show_value(local_obj):
try:
val = local_obj.value
except AttributeError:
logging.debug('值不存在')
else:
logging.debug('value=%s', val) def worker(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',
) class MyLocal(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.py
-- ::, (MainThread) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>
-- ::, (MainThread) value=
-- ::, (Thread- ) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>
-- ::, (Thread- ) value=
-- ::, (Thread- ) value=
-- ::, (Thread- ) 初始化值 <__main__.MyLocal object at 0x7fe58b6e1408>
-- ::, (Thread- ) value=
-- ::, (Thread- ) value=

Python之threading模块的使用的更多相关文章

  1. python中threading模块详解(一)

    python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...

  2. Python使用Threading模块创建线程

    使用Threading模块创建线程,直接从threading.Thread继承,然后重写__init__方法和run方法: #!/usr/bin/python # -*- coding: UTF-8 ...

  3. 再看python多线程------threading模块

    现在把关于多线程的能想到的需要注意的点记录一下: 关于threading模块: 1.关于 传参问题 如果调用的子线程函数需要传参,要在参数后面加一个“,”否则会抛参数异常的错误. 如下: for i ...

  4. python中threading模块中最重要的Tread类

    Tread是threading模块中的重要类之一,可以使用它来创造线程.其具体使用方法是创建一个threading.Tread对象,在它的初始化函数中将需要调用的对象作为初始化参数传入. 具体代码如下 ...

  5. 学会使用Python的threading模块、掌握并发编程基础

    threading模块 Python中提供了threading模块来实现线程并发编程,官方文档如下: 官方文档 添加子线程 实例化Thread类 使用该方式新增子线程任务是比较常见的,也是推荐使用的. ...

  6. Python之Threading模块

    Thread 先引入一个例子: >>> from threading import Thread,currentThread,activeCount >>> > ...

  7. Python(多线程threading模块)

    day27 参考:http://www.cnblogs.com/yuanchenqi/articles/5733873.html CPU像一本书,你不阅读的时候,你室友马上阅读,你准备阅读的时候,你室 ...

  8. python中threading模块中的Join类

    join类是threading中用于堵塞当前主线程的类,其作用是阻止全部的线程继续运行,直到被调用的线程执行完毕或者超时.具体代码如下: import threading,time def doWai ...

  9. Python中threading模块的join函数

    Join的作用是阻塞进程直到线程执行完毕.通用的做法是我们启动一批线程,最后join这些线程结束,例如: for i in range(10): t = ThreadTest(i) thread_ar ...

随机推荐

  1. Mysql中多表删除

    1.从MySQL数据表A中把那些id值在数据表B里有匹配的记录全删除掉 DELETE t2 FROM A t1,B t2 WHERE t1.id = t2.id DELETE FROM t2 USIN ...

  2. 剑指offer10:2*1的小矩形横着或者竖着去覆盖2*n的大矩形,总共有多少种方法?

    1. 题目描述 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 2.思路和方法 思路:(下面说到的x*y的矩形,x是宽 ...

  3. 跑跑卡丁车(dp)

    题意:https://www.nitacm.com/problem_show.php?pid=1470 #define IOS ios_base::sync_with_stdio(0); cin.ti ...

  4. C语言基础练习——最大值及其位置(二维数组)

    C语言基础练习——最大值及其位置(二维数组) 时间限制: 1 Sec  内存限制: 10 MB 题目描述 有一个n×m的矩阵,要求编程序求出: 每行元素的最大值,以及其所在的行号和列号.求出所有元素的 ...

  5. T100——动态更改Label的说明

    例子: #設定科目名稱    IF g_prog = 'aapt300' THEN       CALL cl_set_comp_att_text("lbl_apca036",cl ...

  6. Aveva Marine 新建项目001

    1# 项目代号定义,三个字符,例如Abc 2# 新建文件夹,命名为“Abc” 3# 新建文件名为evars.bat文件,放到项目文件夹的根目录 内容为: SET Abc000=项目文件夹路径\Abc0 ...

  7. extjs 表格为可编辑,保存后为不可编辑状态

    画出表格 编辑后 思路:在初始时设置一个状态,panduan='0',此时,就是一个不可编辑的input,当点击编辑时,改变panduan = '1',即可编辑.保存是加入正则表达式的判断,在将pan ...

  8. O053、Attach Volume 操作(Part I)

    参考https://www.cnblogs.com/CloudMan6/p/5624930.html   Volume的最主要用途是做为虚拟磁盘提供给Instance使用.Volume是通过 Atta ...

  9. opencv 单目标模板匹配(只适用于模板与目标尺度相同)

    #include <iostream> #include "opencv/cv.h" #include "opencv/cxcore.h" #inc ...

  10. js 操作对象的小技巧

    来源:https://www.w3cplus.com/javascript/javascript-tips.html 1.使用...运算符合并对象或数组中的对象 同样使用ES的...运算符可以替代人工 ...