0%

Python3 协程:异步编程的核心机制与实战

协程(Coroutine)是 Python 实现高效异步编程的核心技术,尤其适合处理 I/O 密集型任务(如网络请求、文件读写、数据库操作)。它通过「协作式调度」实现并发,避免了线程切换的开销,能在单线程内高效处理成千上万的并发任务。本文将从基础概念到实战应用,全面解析 Python3 协程的使用。

协程的核心概念:为什么需要协程?

在理解协程前,先明确它与线程、进程的区别,以及解决的核心问题:

并发模型 调度方式 切换开销 适用场景 缺点
进程 操作系统调度 最大 CPU 密集型、独立内存空间 内存占用高,切换成本高
线程 操作系统调度 中等 I/O 密集型、共享内存 受 GIL 限制(Python),切换有开销
协程 程序自身调度 最小 高并发 I/O 密集型 需手动处理异步逻辑,不适合 CPU 密集

协程的核心优势:

  1. 轻量级:一个进程可包含上千个协程,每个协程仅占用几 KB 内存(线程通常需 MB 级)。
  2. 无锁竞争:协程在单线程内执行,共享资源无需加锁(避免死锁问题)。
  3. 高效切换:协程切换由程序主动控制(如遇到 I/O 时暂停),无需操作系统介入,切换速度比线程快 100+ 倍。

Python3 协程的演进:从 yieldasync/await

Python 协程的语法经历了多次迭代,目前推荐使用 Python3.5+ 引入的 async/await 语法(简洁、直观,是官方标准)。

版本 协程实现方式 特点
Python3.3- yield/yield from 基于生成器模拟,语法繁琐
Python3.5+ async def/await 原生协程语法,清晰直观,支持异步库
阅读全文 »

Python3 线程:多任务并发编程详解

线程(Thread)是 Python 实现并发编程的重要方式,适合处理 I/O 密集型任务(如网络请求、文件读写)。Python3 通过 threading 模块提供了完善的线程支持,本文将详细介绍线程的创建、管理、同步及实战应用。

线程的基本概念

  • 线程:操作系统调度的最小单位,属于进程的一部分,多个线程共享进程的内存空间。
  • 并发:多个任务交替执行(单核 CPU 模拟多任务)。
  • 并行:多个任务同时执行(多核 CPU 真正同时运行)。
  • Python 线程特点:
    • 受 GIL(全局解释器锁)限制,CPU 密集型任务多线程效率可能不如单线程;
    • I/O 密集型任务(如网络请求、文件读写)能显著提升效率。

线程的创建与启动

Python3 中创建线程主要有两种方式:使用 threading.Thread继承 threading.Thread 类重写 run() 方法

方式一:直接使用 threading.Thread

通过 threading.Thread(target=函数名, args=参数) 创建线程对象,调用 start() 启动线程。

阅读全文 »

PHP8 引用传递和值传递:变量传递机制详解

在 PHP 中,函数参数的传递方式有两种:值传递(默认值)和引用传递。理解这两种机制的区别对于助于理解变量在函数内外的交互方式,避免意外的变量修改或性能问题。

值传递(Pass by Value)

值传递是 PHP 中默认的参数传递方式。当使用值传递时,函数会接收参数的副本,函数内部对参数的修改不会影响外部原始变量。

1
2
3
4
5
6
7
8
9
10
11
<?php
function increment($number) {
$number++; // 修改的是参数的副本
echo "函数内部:{$number}<br>"; // 输出:函数内部:11
}

$original = 10;
increment($original);
echo "函数外部:{$original}"; // 输出:函数外部:10(原始变量未改变)
?>

值传递的特点:

  • 函数内部操作的是原始值的副本,不影响外部变量
  • 适合传递简单类型(整数、字符串、布尔值等)
  • 传递大型变量(如大数组)时,会复制数据,可能消耗更多内存

引用传递(Pass by Reference)

引用传递允许函数接收变量的内存地址,而非值的副本。函数内部对参数的修改会直接影响外部原始变量,无需返回值即可同步变化。

引用传递通过在参数前添加 & 符号声明。

1
2
3
4
5
6
7
8
9
10
11
<?php
function incrementByReference(&$number) { // 参数前加&表示引用传递
$number++; // 直接修改原始变量
echo "函数内部:{$number}<br>"; // 输出:函数内部:11
}

$original = 10;
incrementByReference($original);
echo "函数外部:{$original}"; // 输出:函数外部:11(原始变量被修改)
?>

阅读全文 »

PHP8 类和接口:面向对象编程的核心

PHP8 对面向对象编程(OOP)进行了多项增强,引入了新特性并改进了现有功能,使类和接口的使用更加灵活和强大。本文将详细介绍 PHP8 中类和接口的定义、特性及新功能。

类的基本概念与定义

类是面向对象编程的基本构建块,用于封装数据和操作数据的方法。

1. 基本类定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
class Person {
// 属性
public $name;
public $age;

// 构造方法
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}

// 方法
public function greet() {
return "Hello, my name is {$this->name} and I'm {$this->age} years old.";
}

public function birthday() {
$this->age++;
}
}

// 创建对象
$person = new Person("John", 30);
echo $person->greet(); // 输出:Hello, my name is John and I'm 30 years old.

$person->birthday();
echo $person->greet(); // 输出:Hello, my name is John and I'm 31 years old.
?>

2. 属性与访问修饰符

PHP 支持三种访问修饰符,用于控制类成员的访问权限:

阅读全文 »

PHP8 常量:定义、使用与高级特性

常量是在脚本执行过程中值不能改变的标识符,与变量相比,常量具有全局可见性(默认情况下)和不可修改的特性。PHP8 对常量的处理进行了增强,提供了更灵活的定义方式和更多功能。本文将详细介绍 PHP8 中常量的定义、类型、作用域及新特性。

常量的基本概念与定义方式

1. 常量的特点

  • 常量的值在定义后不能被修改或重新定义
  • 常量默认具有全局作用域,可在脚本任何地方访问
  • 常量名通常使用大写字母,多个单词用下划线分隔(如 MAX_SIZE
  • 常量可以是标量类型(整数、浮点数、字符串、布尔值)或数组,PHP7 后支持类常量为数组

2. 定义常量的方式

(1)define() 函数(传统方式)

define() 函数是定义常量的传统方式,适用于全局常量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// 定义标量常量
define('PI', 3.14159);
define('SITE_NAME', 'My Website');
define('ENABLED', true);

// 定义数组常量(PHP7+支持)
define('FRUITS', ['apple', 'banana', 'cherry']);

// 使用常量(无需$符号)
echo PI; // 输出:3.14159
echo SITE_NAME; // 输出:My Website
echo ENABLED ? '启用' : '禁用'; // 输出:启用
echo FRUITS[1]; // 输出:banana
?>

(2)const 关键字(推荐方式)

const 关键字在 PHP5.3+ 引入,是定义常量的语言结构,比 define() 更高效,推荐优先使用。

阅读全文 »