前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python的requests模块的介绍、多线程和多进程(5.0)

python的requests模块的介绍、多线程和多进程(5.0)

作者头像
友儿
发布2022-09-28 13:24:37
2.4K0
发布2022-09-28 13:24:37
举报
文章被收录于专栏:友儿

requests模块的介绍

requests的作用

通过python来模拟请求网址

一个模拟请求由以下四个部分组成

  • url
  • method
  • body
  • headers

模拟请求百度

代码语言:javascript
复制
 没有安装requests库的同学, 在当前python环境下执行以下语句安装第三方库
 pip install requests

代码语言:javascript
复制
import requests


def request_baidu():
    url = "https://www.baidu.com/"
    # body = ""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
    }
    response = requests.get(url=url, headers=headers)
    print(response.text)

理解多线程和多进程

什么是进程?什么是线程?

  • 进程: 可以简单地认为是一个程序. 进程是操作系统分配资源的最小单位.
  • 线程: 一个进程可以有多个线程, 每个线程可以独立完成一些任务. 线程是操作系统进行运算调度的最小单位.

多线程demo

代码语言:javascript
复制
from threading import Thread    
for i in range(10):
    # 只是创建了线程对象
    t = Thread(target=request_baidu)
    # 启动线程
    t.start()

多进程demo

代码语言:javascript
复制
from multiprocessing import Process   
for i in range(10):
    # 只是创建了进程对象
    p = Process(target=request_baidu)
    # 启动进程
    p.start()

多线程

等待任务完成后回到主进程

通过调用Thread对象的join方法

代码语言:javascript
复制
# 保存当前thread对象
thread_array = []
for i in range(10):
    t = Thread(target=request_baidu, args=(i, ))
    thread_array.append(t)
    t.start()
# 调用thread对象join接口, 等待任务完成后回到主进程
for t in thread_array:
    t.join()
print("done!")

如何拿到返回结果

赋值到全局变量当中, 添加到可变对象之中

代码语言:javascript
复制
result = []
def request_baidu(index):
    ...
    result.append(response)
    
if __name__ == "__main__":
    thread_array = []
    for i in range(10):
        t = Thread(target=request_baidu, args=(i, ))
        thread_array.append(t)
        t.start()
    for t in thread_array:
        t.join()
    print("done!")
    print(result)

多进程

等待任务完成后回到主进程

通过调用Process对象的join方法

如何拿到返回结果

无法通过全局变量存储返回结果.

多进程相当于启动了多个程序, 共同执行了同一份代码, 他们之间的内存地址完全不一样

代码语言:javascript
复制
import requests
import time
from threading import Thread
from multiprocessing import Process

result = []
print(f"主进程result内存地址: {id(result)}")

def request_baidu(index):
    time.sleep(2)
    url = "https://www.baidu.com/"
    # body = ""
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36"
    }
    response = requests.get(url=url, headers=headers)
    print(f"当前请求序号: {index}, 返回结果状态码: {response.status_code}")
    print(f"子进程result内存地址: {id(result)}")
    result.append(response)

# 如果没有判断入口代码段if __name__ == "__main__", 多进程程序会报错
# 原因是windows和pycharm的进程阻塞带来的问题
if __name__ == "__main__":
    process_array = []
    for i in range(10):
        p = Process(target=request_baidu, args=(i, ))
        process_array.append(p)
        p.start()
    for p in process_array:
        p.join()
    print("done!")
    print(result)

多进程和多线程的异同点

  • 相同点
    • 都是对cpu工作时间段的描述, 只是颗粒度不同. 简单地说就是多进程和多线程都会调用cpu资源的, 但是进程可以启动多个线程去执行.
    • linux内核态不区分进程和线程
  • 不同点
    • 进程有自己的独立地址空间, 建立数据表来维护代码段, 堆栈段和数据段, 而线程共享进程中的资源, 使用相同的地址空间, 所以线程间的切换快得多.
    • 因为线程共享进程的全局变量, 静态变量等对象, 线程间的通信更为方便, 而进程间的通信更加复杂, 需要以ipc的方式进行.
    • 多进程要比多线程要健壮. 进程之间一般不会相互影响, 而多线程有一条线程崩溃, 会导致整个进程跟着发生崩溃或者无法正常退出等.

全局解释器锁(GIL)

  • 计算密集型 主要占用cpu资源
  • IO密集型 IO就是input output, 需要等待的一些任务
    • 网络请求会有网络延迟
    • 和数据库交互需要等待数据库查询事件
    • 读写硬盘
  • 多进程在处理计算密集型程序的时候比多线程块 由于全局解释器锁的存在, 一个进程下, 只允许一个线程执行Python程序的字节码(当前代码文件的二进制表示). 简单地说, 创建的10个线程其实在争夺一个cpu资源. 但是遇到io操作会让渡cpu资源.
  • 如何绕过GIL?
    • 将多线程方法改为多进程
    • 将计算密集型任务转移给C扩展.
    • 分布式计算引擎spark, Apache
    • 使用PyPy解释器, 工业上几乎没人这么用, 因为PyPy并不成熟.
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 09 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • requests模块的介绍
  • 理解多线程和多进程
  • 全局解释器锁(GIL)
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档