python 多线程一点研究,有待深入
# 线程模块
在 Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。
- _thread 提供了低级别的、原始的线程以及一个简单的锁
- threading 对_thread 进行封装并且扩展了功能,所以现在基本上 python 多线程都使用 threading
# 创建线程
- 方法一:
# 使用函数的方式创建 | |
import threading | |
import time | |
def func(arg): | |
time.sleep(1) | |
print('thread '+str(arg)+" running....") | |
if __name__ == '__main__': | |
for i in range(10): | |
t = threading.Thread(target=func, args=(i,)) | |
t.start() |
- 方法二:
# 使用继承 Thread 类的方式创建 | |
import threading | |
class MyThread(threading.Thread): | |
def __init__(self, thread_name): | |
# 注意:一定要显式的调用父类的初始化函数。 | |
super(MyThread, self).__init__(name=thread_name) | |
def run(self): | |
print("%s正在运行中......" % self.name) | |
if __name__ == '__main__': | |
for i in range(10): | |
MyThread("thread-" + str(i)).start() #此行代码也可分开写,先创建 MyThread 对象,在调用 start 方法 |
# 疑惑
start和join干了什么?ctrl+ 左键点击进去 start 源码看到注释:
"""Start the thread's activity. | |
It must be called at most once per thread object. It arranges for the | |
object's run() method to be invoked in a separate thread of control. | |
This method will raise a RuntimeError if called more than once on the | |
same thread object. | |
""" |
简单来说就是激活一个线程,在 run () 方法之后被独立调用,重复调用会抛出 RuntimeError
"""Wait until the thread terminates. | |
This blocks the calling thread until the thread whose join() method is | |
called terminates -- either normally or through an unhandled exception | |
or until the optional timeout occurs. | |
When the timeout argument is present and not None, it should be a | |
floating point number specifying a timeout for the operation in seconds | |
(or fractions thereof). As join() always returns None, you must call | |
is_alive() after join() to decide whether a timeout happened -- if the | |
thread is still alive, the join() call timed out. | |
When the timeout argument is not present or None, the operation will | |
block until the thread terminates. | |
A thread can be join()ed many times. | |
join() raises a RuntimeError if an attempt is made to join the current | |
thread as that would cause a deadlock. It is also an error to join() a | |
thread before it has been started and attempts to do so raises the same | |
exception. | |
""" |
join () 会一直等待知道所有线程结束
就方法一中的代码如果直接在 for 循环中加入 join 的话会导致执行时间为 10s
正确做法:
import threading | |
import time | |
def func(arg): | |
time.sleep(1) | |
print('thread '+str(arg)+" running....") | |
if __name__ == '__main__': | |
start = time.time() | |
threads = [] | |
for i in range(10): | |
t = threading.Thread(target=func, args=(i,)) | |
threads.append(t) | |
for t in threads: | |
t.start() | |
for t in threads: | |
t.join() | |
print(time.time() - start) |
- 同时写入多个文件
import threading | |
import time | |
def func_fs(name): | |
with open(f"{name}.txt", "w") as target: | |
time.sleep(5) # 假装写入很久 | |
target.write("这是一段很长的文本") | |
if __name__ == "__main__": | |
start = time.time() | |
l_thread = [] | |
for i in range(2): | |
t = threading.Thread(target=func_fs, args=(i,)) | |
l_thread.append(t) | |
for t in l_thread: | |
t.start() | |
for t in l_thread: | |
t.join() | |
print(time.time() - start) |
# Todo
- lock
- 生产者消费者模型
- Queue 队列
- 爬虫实战
# 参考链接:
threading
_thread