"""
Python中的进程和线程
进程会启动一个解释器进程,线程共享一个解释器进程
Python的线程开发使用标准库threading
Thread类
参数名 含义
target 线程调用的对象,就是目标函数
name 为这个线程起个名字
args 为目标函数传递实参,元组
kwargs 为目标函数关键字传参,字典
线程退出
1.线程函数内语句执行完毕
2.线程函数中抛出未处理的异常
threading的属性和方法
名称 含义
currrent_thread() 返回当前线程对象
main_thread() 返回主线程对象
active_count() 当前处于alive状态的线程个数
enumerate() 返回所有活着的线程的列表,不包括已经终止的线程和未开始的线程
get_ident() 返回当前线程的ID,非0整数
名称 含义
start() 启动线程。每一个线程必须且只能执行该方法一次 真正多线程
run() 运行线程函数 没有启动新的线程,就是在主线程中调用普通的函数
"""
import threading
def worker():
print('welcome hz')
print('Thread over')
t= threading.Thread(target=worker)
t.start()
class MyThread(threading.Thread):
def run(self):
print('run')
super().run()
def start(self):
return super().start()
import threading
import logging
logging.basicConfig(level=logging.INFO)
def worker():
for x in range(100):
msg = "{} is running".format(threading.current_thread())
logging.info(msg)
for x in range(5):
threading.Thread(target=worker,name="worker-{}".format(x)).start()
"""
daemon线程和non-daemon线程
进程靠线程执行代码,至少有一个主线程,其他线程是工作线程
主线程是第一个启动的线程
父线程:如果线程A中启动了一个线程B,A就是B的父线程
t.join()
一个线程中调用另一个线程的join方法,调用者将被阻塞,知道被调用线程终止。
一个线程可以被join多次
timeout参数指定调用者等待多久,没有设置超时,就一直等到被调用线程结束
调用谁的join方法,就是join谁,就要等谁。
"""
"""threading.local"""
import threading
import time
a = threading.local()
def worker():
a.x= 0 # 局部变量不用上锁
for i in range(100):
time.sleep(0.0001)
a.x+=1
print(threading.current_thread(),a.x)
for i in range(10):
threading.Thread(target=worker).start()
"""
threading.local类构建了一个大字典,其元素是每一线程实例的地址为key和线程对象的引用线程单独的
字典的映射
{id(Thread) ->(ref(Thread),thread-local dict)}
通过threading.local实例就可在不同的线程中,安全地使用线程独有的数据,做到了线程间数据隔离,如同
本地变量一样安全
import threading
import time
def add(x,y):
print(x+y)
t = threading.Timer(3,add,args=(4,5))
t.start()
time.sleep(2)
t.cancel()
"""
threading.Timer继承自Thread,这个类用来定义多久执行一个函数
class threading.Timer(interval,function,args=None,kwargs=None)
start方法执行之后,Timer对象会处于等待状态,等待了interval之后,开始执行func函数
如果在执行函数之前的等待阶段使用了cancel方法,就会跳过执行函数结束
"""