python 多线程一点研究,有待深入

# 线程模块

在 Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。

  • _thread 提供了低级别的、原始的线程以及一个简单的锁
  • threading 对_thread 进行封装并且扩展了功能,所以现在基本上 python 多线程都使用 threading

# 创建线程

  1. 方法一:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 使用函数的方式创建
    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()
  2. 方法二:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 使用继承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方法

# 疑惑

  1. startjoin 干了什么?

    ctrl + 左键点击进去 start 源码看到注释:

    1
    2
    3
    4
    5
    6
    7
    8
    """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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    """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

    正确做法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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)

  2. 同时写入多个文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    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

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

折花载酒z 微信支付

微信支付

折花载酒z 支付宝

支付宝

折花载酒z 贝宝

贝宝