时间:2021年7月18日
作者:Afollower
分类: 学习记录/Python基础
1. 线程的基础:
1.1 线程创建
t = threading.Thread(target=func, name=None, args=(), kwargs={}, verbose=None, daemon=None)
1.2 守护线程
threading.Thread()支持守护线程
1.2.1 说明
守护线程:将一个线程设为守护线程,就表示这个现场不重要,
进程退出时就不需要等待这个线程执行完成。(Python程序在所有非守护线程退出后才退出)
1.2.2 设置为守护线程
1. 创建时
t = threading.Thread(target=func, args=(), daemon=True)
2. 创建后
t.daemon = True
1.3 同步原语(自带)
1.3.1 同步和异步
1. 同步
同步:依次进行,需要获得程序输出,后一个进程需要前一个进程的输出。
使用:修改数据库,更新文件或其他会产生竟态条件的类似情况。
2. 异步
异步:加载资源完就进行,不需要等待程序输出。
1.3.2 锁/互斥
from threading import Lock
lock = Lock()
lock.acquire() #请求锁,没获取到则等待
lock.release() #释放锁
1.3.3 信号量
from threading import BoundedSemaphore
semaphore = BoundedSemaphore(max) #信号量限制,设置计数器
semaphore.acquire(False) #获取信号量,计数器减一,非阻塞标识-False
semaphore.release() #释放信号量,计数器加一
2. 多线程创建方式总结
2.1 创建Thread实例,并传给它一个函数
import sys
import threading
from time import ctime, sleep
def print_func(things: str, sleep_time):
for i in range(3):
sleep(sleep_time)
print('start {} at {} print: {}'.format(sys._getframe().f_code.co_name, ctime(), things))
def thread_used1():
"""
创建Thread实例,传给它一个函数
"""
print_things = ['func1', 'func2']
threads = []
for i in range(len(print_things)):
t = threading.Thread(target=print_func, args=(print_things[i], i + 1))
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
if __name__ == '__main__':
thread_used1()
2.2 创建Thread实例,并传给它一个类实例
import sys
import threading
from time import ctime, sleep
def print_func(things: str, sleep_time):
for i in range(3):
sleep(sleep_time)
print('start {} at {} print: {}'.format(sys._getframe().f_code.co_name, ctime(), things))
class ThreadFunc:
def __init__(self, func, args):
self.func = func
self.args = args
def __call__(self, *args, **kwargs):
return self.func(*self.args)
def thread_used2():
"""
创建Thread实例,传给它一个可调用的类实例
"""
print_things = ['func1', 'func2']
threads = []
for i in range(len(print_things)):
t = threading.Thread(target=ThreadFunc(print_func, (print_things[i], i)))
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
if __name__ == '__main__':
thread_used2()
2.3 派生Thread 子类,并创建子类的实例
import sys
import threading
from time import ctime, sleep
def print_func(things: str, sleep_time):
for i in range(3):
sleep(sleep_time)
print('start {} at {} print: {}'.format(sys._getframe().f_code.co_name, ctime(), things))
class MyThread(threading.Thread):
def __init__(self, func, args):
threading.Thread.__init__(self)
self.args = args
self.func = func
def run(self):
self.func(*self.args)
def thread_used3():
"""
派生Thread的子类,并创建子类的实例
"""
print_things = ['func1', 'func2']
threads = []
for i in range(len(print_things)):
t = MyThread(print_func, (print_things[i], i))
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
if __name__ == '__main__':
thread_used3()