python线程join()方法使用

首先创建两个子线程

def get_target_html():
    print("获取目标网址start\n")
    time.sleep(2)
    print("获取目标网址end\n")


def get_target_url():
    print("获取目标URL,start\n")
    time.sleep(2)
    print("获取目标URL,end\n")


if __name__ == '__main__':
    start_time = time.time()
    print('这是主线程:{}'.format(threading.current_thread().name))  
    # 在未指定的情况下,main函数默认为主线程

    thread1 = threading.Thread(target=get_target_html, name="html") # 创建子线程1
    thread2 = threading.Thread(target=get_target_url, name="url")  # 创建子线程2

    thread1.start() # 启动子线程1
    thread2.start() # 启动子线程2

    print('主线程结束了!{}'.format(threading.current_thread().name))
    print('一共用时:{}'.format(time.time() - start_time))

运行查看结果为

 可以看出主线程在两个子线程运行完成之前就结束了,两个子线程继续执行直至完成。

但有时我们希望所有的子线程都执行完成再结束主线程,此时需要用到join()

def get_target_html():
    print("获取目标网址start\n")
    time.sleep(2)
    print("获取目标网址end\n")


def get_target_url():
    print("获取目标URL,start\n")
    time.sleep(2)
    print("获取目标URL,end\n")


if __name__ == '__main__':
    start_time = time.time()
    print('这是主线程:{}'.format(threading.current_thread().name))

    thread1 = threading.Thread(target=get_target_html, name="html")
    thread2 = threading.Thread(target=get_target_url, name="url")

    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()

    print('主线程结束了!{}'.format(threading.current_thread().name))
    print('一共用时:{}'.format(time.time() - start_time))

 target.join(),会阻塞其它的线程直至target线程执行完成/抛出异常。

所以运行流程为:main线程启动-->thread1启动--->thread2启动--->thread1与2均阻塞main线程运行-->thread1与2并行运行-->thread1与2运行完毕--->main线程运行结束

可以参考官方解释:

    def join(self, timeout=None):
        """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.

此外需要注意的错误,区分赋值操作时带()与不带()的区别

def get_target_html():
    print("获取目标网址start\n")
    time.sleep(2)
    print("获取目标网址end\n")


def get_target_url():
    print("获取目标URL,start\n")
    time.sleep(2)
    print("获取目标URL,end\n")


if __name__ == '__main__':
    start_time = time.time()
    print('这是主线程:{}'.format(threading.current_thread().name))

    thread1 = threading.Thread(target=get_target_html(), name="html")
    thread2 = threading.Thread(target=get_target_url(), name="url")

    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()

    print('主线程结束了!{}'.format(threading.current_thread().name))
    print('一共用时:{}'.format(time.time() - start_time))

笔者在第一次写程序时,在调用两个子线程方法时加上了(),类不带括号---赋值,带括号---实例化

因此在执行

thread1 = threading.Thread(target=get_target_html(), name="html")
thread2 = threading.Thread(target=get_target_url(), name="url")

时,target=get_target_html(), target=get_target_url()会自动实例化并执行方法中的语句,无论加不加join()语句,主线程的运行时间一定会≥4s

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值