# !/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}\n")
except StopIteration:
print(f"{self.name}的第{count}次发送请求发现所有url地址都已请求完!!!\n")
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)