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
    评论
Python 中,可以使用线程列表和 join() 方法来实现多线程编程。 线程列表是一个包含多个线程对象的列表。每个线程对象都可以执行一个函数或方法join() 方法用于等待所有线程完成。当所有线程完成后,join() 方法返回。 以下是一个简单的示例,使用线程列表和 join() 方法实现多线程编程: ```python import threading # 定义一个线程类,继承自 threading.Thread class MyThread(threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num def run(self): print("Thread " + str(self.num) + " started") # 线程执行的代码 print("Thread " + str(self.num) + " finished") # 创建一个线程列表 threads = [] # 创建 5 个线程 for i in range(5): t = MyThread(i) threads.append(t) # 启动所有线程 for t in threads: t.start() # 等待所有线程完成 for t in threads: t.join() print("All threads finished") ``` 在上面的例子中,我们创建了一个 MyThread 类,它继承自 threading.Thread 类。MyThread 类的构造函数接受一个参数 num,用于标识线程。run() 方法线程执行的方法,我们在这里打印线程的编号和一些消息。 接下来,我们创建了一个线程列表 threads,并向其中添加 5 个 MyThread 对象。然后,我们启动所有线程,并使用 join() 方法等待所有线程完成。最后,我们打印一条消息,表示所有线程都已完成。 注意,在 Python 中,线程列表和 join() 方法可以用于控制线程的执行顺序和并发性。如果需要更高级的线程控制,可以使用 Python 中的线程锁、条件变量、信号量等同步原语。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值