# !/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2020/5/26 22:48 # @Author : "小多肉" # @Email : 1021181701@qq.com # @File : 多线程.py # @Software: PyCharm #TODO: ############################ # 并发和并行的区别 ########################### """ 并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。 并行在多处理器系统中存在,而并发可以在单处理器和多处理器系统中都存在,并发能够在单处理器系统中存在是因为并发是并行的假象,并行要求程序能够同时执行多个操作,而并发只是要求程序假装同时执行多个操作(每个小时间片执行一个操作,多个操作快速切换执行)。 当有多个线程在操作时,如果系统只有一个 CPU,则它根本不可能真正同时进行一个以上的线程,它只能把 CPU 运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状态.这种方式我们称之为并发(Concurrent)。 当系统有一个以上 CPU 时,则线程的操作有可能非并发。当一个 CPU 执行一个线程时,另一个 CPU 可以执行另一个线程,两个线程互不抢占 CPU 资源,可以同时进行,这种方式我们称之为并行(Parallel)。 """ ####################################### # 2、简单描述python线程的缺陷,以及适用场景 ######################################## """ python线程的缺陷: 1、不能做到真正的并行 2、在多线程共享全局变量时,会因为资源竞争,导致全局变量数据不正确。 适用场景: 1、多进程适合在cpu 密集型操作(cpu 操作指令比较多,如位数多的浮点运算) 2、多线程适合在 IO密集型操作(读写数据操作比较多的,比如爬虫) """ ############################################################### # 3、一个列表中有100个url地址(假设请求每个地址需要0.5秒),请设计一个程序,获取列表中的url地址,使用4个线程去发送这100个请求,计算出总耗时! ############################################################### from threading import Thread import requests import time # 全局变量 url_list = [] for i in range(100): url_list.append("http://www.baidu.com") url_iter = iter(url_list) class MyThread(Thread): def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None): super().__init__(group=group, target=target, name=name, args=args, kwargs=kwargs, daemon=daemon) self.name = name def run(self): count = 0 while True: count += 1 try: res = requests.get(url_iter.__next__()) time.sleep(0.5) print(f"{self.name}第{count}次发送请求,请求结果:{res.status_code} ") except StopIteration: print(f"{self.name}的第{count}次发送请求发现所有url地址都已请求完!!! ") break if __name__ == '__main__': threads = [] start = time.time() # 创建4个线程,并加入线程池 for i in range(4): my_thread = MyThread(name=f"Thread-{i}") my_thread.start() threads.append(my_thread) # 等待所有线程完成 for t in threads: t.join() end = time.time() print("总耗时:", end - start)