def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)
target
name
args
kwargs
threading.Thread(target=fn, name=‘fn‘).start()
Python线程没有优先级、没有线程组的概念,不能被销毁、停止、挂起、恢复、中断
current_thread()
main_thread()
active_count()
enumerate()
name
ident
is_alive()
start()
if not self._initialized:
raise RuntimeError("thread.__init__() not called")
if self._started.is_set():
raise RuntimeError("threads can only be started once")
with _active_limbo_lock:
_limbo[self] = self
try:
_start_new_thread(self._bootstrap, ())
except Exception:
with _active_limbo_lock:
del _limbo[self]
raise
self._started.wait()
run()
try:
if self._target:
self._target(*self._args, **self._kwargs)
finally:
# Avoid a refcycle if the thread is running a function with
# an argument that has a member that points to the thread.
del self._target, self._args, self._kwargs
每次调用run都会删除引用self._target, self._args, self._kwargs
import threading
import time
class MyThread(threading.Thread):
def start(self):
print(‘-----start-----‘)
super().start()
def run(self):
print(‘---------run----------‘)
super().run()
def pr1(lst):
for _ in lst:
print(‘{} is running‘.format(threading.current_thread().name))
def worker():
name = ‘worker{}‘.format(1)
t = MyThread(target=pr1, name=name, args=([1, 2],))
# time.sleep(.5)
t.start()
# time.sleep(1)
t.run()
if __name__ == ‘__main__‘:
worker()
结果(可能发生):
线程执行一段代码,不会产生不确定行结果,那这段代码是线程安全的
import threading
def worker():
for x in range(100):
print("{} is running.".format(threading.current_thread().name))
for x in range(5):
name="worker{}".format(x)
t=threading.Thread(name=name,target=worker)
t.start()
print("{} is running.\n".format(threading.current_thread().name), end=‘‘)
2.logging
日志处理模块,线程安全
import threading
import logging
def worker():
for x in range(100):
logging.warning("{} is running.".format(threading.current_thread().name))
for i in range(1,6):
name="worker{}".format(i)
t=threading.Thread(name=name,target=worker)
t.start()
daemon=True
daemon=False
daemon必须在start()之前设置,否则引发RuntimeError异常
isDaemon()
setDaemon
继承自Thread,用来定义多久执行一个函数
线程同步,线程间协同,通过锁,让一个线程访问某些数据时,其他线程不能访问这些数据,直到该线程完成对数据的操作
是线程间通信机制中最简单的实现,使用一个内部的标记flag的变化来操作
set()
clear()
is_set()
使用同一个Event对象的标记flag
不限制等待的个数wait效率优于time.sleep,它会更快切换线程,提高并发效率
一旦线程获得锁,其他试图获取锁的线程将被阻塞
acquire(blocking=True, timeout=-1)
锁保护了数据完整性,但是性能下降很多
import threading
import time
import logging
FORMAT = ‘%(asctime)-15s\t [%(threadName)s %(thread)8d] %(message)s‘
logging.basicConfig(format=FORMAT, level=logging.INFO)
def worker(tasks):
for task in tasks:
time.sleep(0.001)
if task.lock.acquire(False):
logging.info(‘{} {} begin to start‘.format(threading.current_thread(), task.name))
else:
logging.info(‘{} {} is working‘.format(threading.current_thread(), task.name))
class Task:
def __init__(self, name):
self.name = name
self.lock = threading.Lock()
tasks = [Task(‘task-{}‘.format(x)) for x in range(10)]
for i in range(5):
threading.Thread(target=worker, name=‘worker-{}‘.format(i), args=(tasks,)).start()
线程A获得可重复锁,并可以多次成功获取,不会阻塞。最后要在线程A中做和acquire次数相同的release
Condition(lock=None),可以传入一个Lock或Rlock对象,默认是Rlock
acquire(*args)
wait(self, timeout=None)
notify(n=1)
notify_all()
原文:http://blog.51cto.com/11281400/2120804