【PHP 8.1 纤维深度解析】:掌握 suspend/resume 协程黑科技,提升并发性能300%

第一章:PHP 8.1 纤维与协程的革命性演进

PHP 8.1 引入了“纤维(Fibers)”这一核心特性,标志着 PHP 在异步编程领域迈出了历史性的一步。纤维提供了一种用户态的轻量级并发机制,允许开发者在单线程内实现协作式多任务调度,为构建高性能的异步应用奠定了语言级基础。

纤维的基本概念

纤维是一种可中断和恢复执行流程的结构,不同于传统的线程,它由程序员显式控制调度,避免了系统级上下文切换的开销。通过 Fiber 类,PHP 允许在任意位置暂停当前执行,并将控制权交还给调用者。
<?php
$fiber = new Fiber(function (): string {
    echo "进入纤维\n";
    $value = Fiber::suspend('已挂起');
    echo "恢复执行,接收值:$value\n";
    return "纤维完成";
});

$result = $fiber->start(); // 输出:进入纤维,返回:已挂起
echo "主流程收到:$result\n";

$result = $fiber->resume('继续执行'); // 输出:恢复执行,接收值:继续执行
echo "最终结果:$result\n"; // 输出:最终结果:纤维完成
上述代码展示了纤维的创建、挂起与恢复过程。调用 start() 启动纤维,执行至 Fiber::suspend() 时暂停并返回控制权;后续通过 resume() 恢复执行,并传递数据。

与传统回调模型的对比

使用纤维可显著提升异步代码的可读性和维护性。相比嵌套回调或 Promise 链,纤维使异步逻辑呈现为同步风格,降低心智负担。
特性传统回调PHP 纤维
代码可读性低(回调地狱)高(线性结构)
错误处理复杂(需层层捕获)简单(可使用 try/catch)
上下文切换开销无极低(用户态)
纤维并非完全替代多进程或多线程模型,而是为 I/O 密集型场景(如 API 聚合、实时消息处理)提供了更优雅的解决方案。结合事件循环库,PHP 应用可实现高并发非阻塞操作,真正迈向现代异步架构。

第二章:深入理解 Fiber 的 suspend/resume 机制

2.1 协程基础与 Fiber 的核心概念

协程是一种用户态的轻量级线程,能够在单个操作系统线程上实现并发执行。与传统线程不同,协程通过主动让出执行权(yield)而非抢占式调度来协作运行,显著降低上下文切换开销。
Fiber 与传统协程的区别
Fiber 是一种更底层的协程实现,允许开发者精确控制执行与暂停。相较于标准协程,Fiber 提供更细粒度的调度能力,适用于高并发 I/O 密集型场景。

func worker(f *fiber.Fiber) {
    fmt.Println("协程开始执行")
    f.Yield() // 主动让出控制权
    fmt.Println("协程恢复执行")
}
上述代码中,f.Yield() 显式暂停当前 Fiber,交出执行权给调度器,待被唤醒后从中断点继续执行,体现协作式调度的核心机制。
执行栈管理
每个 Fiber 拥有独立的执行栈,确保局部变量在挂起期间保持状态。这使得异步逻辑可写成同步形式,提升代码可读性与维护性。

2.2 suspend 与 resume 的工作原理剖析

在操作系统中,`suspend` 和 `resume` 是进程状态管理的核心机制。当系统资源紧张或用户切换应用时,系统会触发 `suspend`,将进程从运行态转入挂起态,释放CPU与内存资源。
状态切换流程
  • suspend:暂停进程执行,保存上下文(寄存器、堆栈、程序计数器)到内存或磁盘;
  • resume:恢复保存的上下文,重新调度进程进入就绪队列。
代码实现示例

void suspend_process(struct process *p) {
    save_context(p);        // 保存寄存器状态
    p->state = SUSPENDED;   // 更新进程状态
    schedule();             // 触发调度
}
上述函数首先保存当前进程的执行上下文,随后将其状态标记为挂起,并调用调度器选择新进程运行。
状态转换对比
操作CPU占用内存保留可恢复性
suspend无是高
resume恢复是立即

2.3 用户态线程调度模型详解

用户态线程(User-Level Threads)由应用程序或运行时库管理,不依赖内核调度。其核心优势在于上下文切换成本低,且可定制化调度策略。
调度器生命周期
用户态线程的调度器通常在程序启动时初始化,负责线程的创建、就绪、运行与阻塞状态转换。当某线程发起 I/O 请求时,调度器主动让出执行权,切换至其他就绪线程。
协作式调度示例

type Scheduler struct {
    threads []*Thread
    index   int
}

func (s *Scheduler) Next() {
    if len(s.threads) == 0 { return }
    curr := s.threads[s.index % len(s.threads)]
    if curr.State == Running {
        curr.Yield() // 主动交出控制权
    }
    s.index++
}
上述代码实现了一个简单的轮转调度器。Scheduler 维护线程列表和当前索引,Next() 方法按序切换线程。每个线程需主动调用 Yield() 进入就绪队列,体现协作式调度特征:无抢占,依赖线程配合。
优缺点对比
优点缺点
切换开销小无法利用多核并行
可实现自定义策略一个线程阻塞会导致整个进程挂起

2.4 Fiber 与传统异步编程的对比分析

在现代高并发系统中,Fiber 作为一种轻量级线程模型,正逐步替代传统的基于回调或 Promise 的异步编程模式。
执行模型差异
传统异步编程依赖事件循环和回调队列,容易导致“回调地狱”。而 Fiber 通过协作式调度实现细粒度控制:

func handleRequest() {
    spawnFiber(func() {
        data := fetchData()
        process(data)
    })
}
上述代码中,spawnFiber 创建一个可中断的执行单元,避免阻塞主线程。相比 Promise 链式调用,逻辑更线性。
资源开销对比
特性传统异步Fiber
栈内存固定大小(如 2MB)动态增长(几 KB 起)
上下文切换成本高(系统线程)低(用户态调度)

2.5 实现一个简单的 suspend/resume 控制流

在协程中实现 suspend/resume 机制,核心是控制执行流程的暂停与恢复。通过定义回调接口,可在异步操作完成时触发继续执行。
基本结构设计
使用函数接收 continuation 参数,表示后续执行逻辑:
suspend fun simpleSuspendOperation(): String = 
    suspendCancellableCoroutine { continuation ->
        // 模拟异步任务
        thread {
            Thread.sleep(1000)
            continuation.resume("Task completed")
        }
    }
上述代码中,suspendCancellableCoroutine 挂起协程,并传入 continuation。当异步任务完成,调用 resume 恢复执行并传递结果。
控制流状态对比
状态协程行为
Suspend释放线程,保存上下文
Resume恢复上下文,继续执行

第三章:Fiber 在实际场景中的应用模式

3.1 异步 I/O 操作中的 Fiber 调度实践

在高并发场景下,传统的线程模型面临栈内存开销大、上下文切换频繁等问题。Fiber 作为一种用户态轻量级线程,能够在单个操作系统线程上高效调度成千上万个协程任务,尤其适用于异步 I/O 密集型应用。
非阻塞 I/O 与 Fiber 协同调度
Fiber 调度器通常集成事件循环(Event Loop),当发起异步 I/O 请求时,Fiber 主动让出执行权,注册回调至 I/O 完成队列,避免阻塞线程。待内核完成数据准备后,事件循环唤醒对应 Fiber,恢复执行上下文。

func asyncRead(file *os.File) []byte {
    fiber.Yield() // 主动让出调度权
    data, _ := ioutil.ReadAll(file)
    return data
}
上述代码中,fiber.Yield() 触发 Fiber 切换,释放当前线程资源。调度器将该 Fiber 挂起并加入等待队列,直到 I/O 完成后重新入队可运行队列。
调度策略对比
策略特点适用场景
FIFO公平性好短任务密集
优先级调度响应关键任务快实时性要求高

3.2 使用 Fiber 构建轻量级任务队列

在高并发场景下,传统同步处理模式容易造成请求阻塞。Fiber 框架凭借其轻量级协程和中间件机制,为构建非阻塞任务队列提供了理想基础。
任务队列设计思路
通过 Fiber 的路由分组与异步中间件,可将耗时任务(如邮件发送、数据清洗)推入内存队列,立即返回响应,提升系统吞吐量。
核心实现代码
app.Post("/task", func(c *fiber.Ctx) error {
    task := c.Body()
    go processTask(task) // 异步协程处理
    return c.JSON(fiber.Map{"status": "queued"})
})
上述代码利用 go processTask() 启动独立协程执行任务,避免阻塞主请求流程,确保快速响应。
性能对比
模式并发能力响应延迟
同步处理低高
Fiber 队列高低

3.3 高并发请求处理的性能优化案例

在某电商平台大促场景中,系统面临每秒数万次的商品查询请求。初始架构采用同步阻塞调用,导致响应延迟高、线程资源耗尽。
异步非阻塞改造
引入 Go 语言的 Goroutine 与 Channel 实现异步处理:
func handleRequest(w http.ResponseWriter, r *http.Request) {
    go func() {
        data := <- fetchDataAsync() // 异步获取数据
        json.NewEncoder(w).Encode(data)
    }()
}
该方式将单个请求处理时间从 200ms 降低至 50ms,并发能力提升 4 倍。
缓存热点数据
使用 Redis 缓存商品信息,设置 TTL 防止雪崩:
  • 缓存命中率提升至 92%
  • 数据库 QPS 下降 70%
通过组合异步处理与缓存策略,系统整体吞吐量达到 12,000 RPS,满足高并发需求。

第四章:性能调优与常见陷阱规避

4.1 如何监控 Fiber 的执行状态与内存使用

在 Go 程序运行过程中,Fiber(协作式多任务轻量执行单元)的执行状态和内存使用情况对性能调优至关重要。通过 runtime 包提供的接口,可实时获取当前 Fiber 的栈指针、协程状态及内存分配信息。
获取运行时指标
使用 runtime.MemStats 可采集内存相关数据:
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc: %d KB, Sys: %d KB, NumGC: %d\n", 
    m.Alloc/1024, m.Sys/1024, m.NumGC)
该代码片段输出当前堆内存分配量、系统内存占用及 GC 次数。Alloc 反映活跃对象内存消耗,NumGC 过高可能暗示频繁的 Fiber 创建与销毁。
关键监控指标对比
指标含义异常表现
Goroutine 数量Fiber 并发数突增可能导致调度延迟
Stack In-Use栈内存使用量持续增长可能暗示泄漏

4.2 避免嵌套 Fiber 导致的调度混乱

在 React 的 Fiber 架构中,每个组件实例对应一个 Fiber 节点,构成树形结构。当出现深层嵌套的 Fiber 树时,可能导致调度任务被频繁中断或堆积,影响渲染性能。
问题根源:递归更新引发的重排
深层嵌套组件在状态更新时会触发自下而上的 Fiber 重建,若未合理控制更新粒度,易造成长时间运行的同步任务,阻塞主线程。
  • 避免在 render 中创建新函数或对象,防止不必要的重渲染
  • 使用 React.memo 缓存子组件
  • 拆分大型组件,降低单个 Fiber 节点的复杂度
function NestedComponent({ items }) {
  return (
    <div>
      {items.map(item => (
        <Child key={item.id} data={item} />
      ))}
    </div>
  );
}
上述代码中,若 items 频繁变更且无 React.memo 优化,将导致大量 Fiber 节点重复创建,加剧调度压力。通过提升组件可预测性,可有效降低协调开销。

4.3 错误处理与异常传递的最佳实践

在现代软件开发中,合理的错误处理机制是保障系统稳定性的关键。应避免忽略错误或使用空的错误处理分支,确保每个潜在异常都被显式处理。
使用明确的错误类型
在 Go 语言中,推荐返回具体错误类型以便调用方判断处理逻辑:
if err != nil {
    if errors.Is(err, os.ErrNotExist) {
        // 处理文件不存在
    }
    return fmt.Errorf("failed to open file: %w", err)
}
该代码通过 fmt.Errorf 的 %w 包装原始错误,保留了错误链信息,便于后续追溯。
统一异常传递规范
  • 禁止在中间层吞掉错误
  • 对外部依赖的错误应进行封装,避免底层细节暴露
  • 使用错误码+描述信息的组合提升可读性

4.4 提升并发性能的关键编码技巧

减少锁的粒度
在高并发场景中,过度使用粗粒度锁会导致线程阻塞。通过将大锁拆分为多个细粒度锁,可显著提升并行处理能力。例如,使用分段锁(Segment Locking)机制:

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.putIfAbsent("key", 1); // 内部采用分段锁,避免全局同步
该代码利用 ConcurrentHashMap 的内部分段机制,允许多个线程同时写入不同键,提升吞吐量。
无锁编程与原子操作
  • 使用 AtomicInteger 等原子类替代 synchronized
  • 借助 CAS(Compare-And-Swap)实现高效并发更新
原子操作避免了线程上下文切换开销,适用于计数器、状态标志等场景。

第五章:未来展望与协程生态的发展方向

语言层面的原生支持演进
现代编程语言正逐步将协程作为一级公民。例如,Kotlin 通过 suspend 函数实现轻量级异步操作,而 Python 的 async/await 语法已深度集成于主流框架中。Go 语言则凭借 goroutine 和 channel 构建了高效的并发模型:

package main

import (
    "fmt"
    "time"
)

func worker(id int, jobs <-chan int) {
    for job := range jobs {
        fmt.Printf("Worker %d processing job %d\n", id, job)
        time.Sleep(time.Second)
    }
}

func main() {
    jobs := make(chan int, 5)
    for i := 1; i <= 3; i++ {
        go worker(i, jobs) // 启动协程
    }
    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)
    time.Sleep(6 * time.Second)
}
微服务架构中的协程优化
在高并发微服务场景下,协程显著降低线程切换开销。例如,使用 Spring WebFlux 构建响应式服务时,单个实例可支撑数万并发连接。典型部署结构如下:
组件传统线程模型协程模型
并发连接数~1k~10k+
内存占用(MB)512128
平均延迟(ms)4518
运行时调度器的智能化发展
新一代协程调度器引入工作窃取(work-stealing)机制,动态平衡负载。以下为典型调度策略对比:
  • 静态分片:固定协程绑定处理器,适用于确定性任务
  • 动态抢占:基于事件反馈调整执行优先级
  • 混合模式:I/O 密集型任务采用协作式,CPU 密集型启用抢占式调度
协程生命周期管理流程图:
创建 → 挂起(等待 I/O) → 调度器唤醒 → 恢复执行 → 完成/取消
Hyperf 高性能PHP协程框架实战(八) 协程 1 阅读详情

相关推荐

PHP关于协程的优点以及swoole 协程的用法

进程与携程流程图 协程的运行是交叉式运行(串行),只要你发起了一次协程切换,则会立马暂停当前协程,去运行下一个协程,直到下次代码调度回协程. 协程的优点 看到上面的执行顺序,你可能还是不能理解协程的优点,这个其实是一个很简单的概念,举个例子: 小明烧开水需要10分钟,刷牙需要3分钟,吃早餐需要5分钟,请问做完这些事情总共需要多少分钟? 答案是10分钟,因为在烧开水这个步骤时,不需要坐在那里看水壶烧(异步,io耗时)可以先去刷牙,然后去吃早餐。 协程的优点主要在于这里,当遇上io耗时的情况

wgchen 695

PHP学习笔记18:协程

PHP学习笔记18:协程 图源:php.net 正如Python关于协程的PEP所讲,异步编程和并发已经是编程的一个热门领域,所以无论是老派语言如Python,或者是新语言Go,要么是添加新特性以支持协程,要么是天生就对协程和并发有完整支持。 但在这方面php就相当落(la)后(kua)了。 或许这和语言的应用领域和使用方式有一些关系,php作为一个和Apache等web service紧密结合的Web开发语言,绝大部分php项目都是依托于web service处理和转发请求的,php本身并不需要花大力气

梦幻天空 2150

Simulink Test Sequence自动化测试实战:从Excel到模型验证

本文详细介绍了如何利用Excel和MATLAB脚本实现Simulink Test Sequence的自动化测试。通过设计结构化Excel模板管理测试数据,并调用Simulink Test API批量创建与执行测试用例,该方法能显著提升复杂模型单元测试的效率,便于集成到CI/CD流程,实现从数据到验证的全自动化。

weixin_29261711的博客 144

PHP8 编程提示(六)

在这个示例中,使用同步编程模型,我们执行三个操作,如下:执行 HTTPGET请求。执行数据库查询。将信息写入访问日志。已经具有一些异步编程知识的你意识到,所有三个任务都代表着阻塞操作。首先,我们定义一个要包含的 PHP 文件,其中定义了回调:},},$info\n";},接下来,我们定义一个包含回调定义并按顺序执行它们的 PHP 程序。我们使用 PHP 8 的match {}结构来为适当的回调分配不同的参数。最后,我们通过简单返回一个字符串并运行strlen()

龙哥盟 1628

NBU计算机大二下期末

计算机网络 任课老师:JG (放了一学期的他自己的视频和上了一学期网课没什么区别,甚至不如上网课。。。) 考试题型 填空题10*1 判断题10*1 选择题30*1 简答和计算题30(4题) 讨论题20 强烈建议不要再这门课上花太多时间复习,不然有复习了个寂寞的感觉。。。计网是一页开卷的,一页开卷纸不用写太多,第一他不会考太详细;第二反正最后都要被收走。 填空题、判断题基本看懂了英文就能做的差不多;选择题去网上找点英文题多刷一下问题不大;简答题把书上每章根据他上课的内容在开卷纸上抄下就好,今年是解释check

weixin_45816954的博客 710

ESXi 6.7升级17700523补丁全流程:从下载到验证的保姆级教程

本文提供ESXi 6.7升级17700523补丁的完整流程指南,涵盖从下载、上传到验证的详细步骤。通过SSH命令和vSphere Client操作,确保系统管理员能够安全高效地完成补丁升级,提升虚拟化环境的安全性和稳定性。

linux6sysadmin的博客 839

在PHP中使用协程实现多任务调度

http://www.laruence.com/2015/05/28/3038.html 28 May 15 在PHP中使用协程实现多任务调度 本文地址: http://www.laruence.com/2015/05/28/3038.html 转载文章 英文原文地址: Cooperative multitasking using corouti

loongwong2011的博客 616

Openbmc系列之自动化测试框架1

Openbmc作为当下BMC固件领域最流行的开源软件,具备从需求计划、开发、调试、测试、版本管理等完整的体系。在测试领域,Openbmc基于python的robotframework框架,实现Openbmc的自动化测试,为高效发布Openbmc版本提供有力支持。本文作为测试系列文档一,介绍Openbmc自动化测试虚拟Openbmc的环境搭建。

qq_20341747的博客 2109

深入解析 PHP 8.1 Fiber:开启轻量级并发编程新时代

Fiber 是 PHP 8.1 新增的一个实验性功能,它允许在一个单独的 PHP 进程中创建多个轻量级线程(也称为协程),这些线程可以独立执行不同的任务而无需额外启动新的进程或线程。相较于传统的多线程或多进程模型,Fiber 提供了更低的资源消耗和更高的灵活性,特别适用于需要频繁进行 I/O 操作或处理大量并发请求的场景。通过上述介绍可以看出,PHP 8.1 中引入的 Fiber 功能确实为 PHP 开发带来了许多新的可能性。

敖行客 Allthinker的博客 1722

Halcon dyn_threshold详解

dyn_threshold 原型 dyn_threshold(OrigImage, ThresholdImage : RegionDynThresh : Offset, LightDark : ) 功能 利用局部阈值分割图像 参数列表 OrigImage (input_object):原始图像 ThresholdImage (input_object):处理后图像(一般采用滤波处理) RegionDynThresh (output_object):分割后区域 Offset (input_control):灰

ZiLiangQin的博客 1万+

第0章 《机器人工程师带你入门SLAM》专栏所有文章目录汇总(截止目前115篇文章),方便大家查看阅读

《机器人工程师带你入门SLAM》专栏文章汇总:优快云热销专栏已更新100+篇优质内容,涵盖SLAM技术全栈知识体系。文章分为三大类:1)基础工具与环境配置,包括Ubuntu、Git等必备技能;2)C++编程从入门到进阶,详解变量、类、模板等核心概念;3)SLAM核心库实战,深入解析ROS、Eigen、PCL等关键库的应用。专栏提供从计算机基础到项目实战的系统学习路径,并附代码实例。点击专栏主页可订阅查看全部内容,后续将保持更新。

行知SLAM 1068

Fiber 初体验

需要注意的是,在 PHP 8 中,Fiber 类为实验性特性,仍然存在一些限制和不足(如无法控制协程数量、无法轻松地进行异步 IO 操作等)

wsy321123的博客 202

Python办公自动化 2.1开发环境搭建:PyCharm社区版配置Anaconda开发环境

本篇文章主要讲述了如何在windows主机上配置 PyCharm + Anaconda开发环境、以及了如何配置 PyQt界面开发环境,安装过程超级详细,初学者可以照着一步一步来!

超级大洋葱的博客 2584

PHP 8 中的 Swow:高性能纯协程网络通信引擎

Swow 是一个高性能的纯协程网络通信引擎,专为 PHP 设计。它结合了最小化的 C 核心和 PHP 代码,旨在提供高性能的网络编程支持。Swow 的核心目标是释放 PHP 在高并发场景下的真正潜力,同时保持代码的简洁和易用性。Swow 是一个高性能的纯协程网络通信引擎,专为 PHP 设计。它通过最小化的 C 核心和 PHP 代码的结合,提供了强大的并发处理能力和高效的网络编程支持。Swow 适用于多种高性能场景,包括 Web 服务器、实时通信和数据流服务。

1693

ABAP Channels 实战:在 ABAP 7.40 中用 WebSocket 打造实时双向通信

本文详细介绍了SAP ABAP 7.40引入的ABAP Channels通信框架,包含AMC(ABAP Messaging Channels)和APC(ABAP Push Channels)两部分。AMC作为应用服务器内部的消息总线,支持发布/订阅模式,可实现跨会话实时通信;APC基于WebSocket协议,用于浏览器等客户端与ABAP服务器的双向实时交互。文章通过一个乒乓球游戏案例展示了ABAP Channels的实时协作能力,并详细解析了AMC的配置方法、消息发送与接收的代码实现,帮助开发者理解如何利用

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 221

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

PHP8 - 纤程的使用

php8 (php8 >= 8.1.0 ) 中新增了纤程特性

我码玄黄的博客 682

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

探索高效并发的新境界:Moebius——PHP 8.1的纯协程时代

探索高效并发的新境界:Moebius——PHP 8.1的纯协程时代 在异步编程的世界里,PHP从未像今天这样接近于简洁与强大的完美平衡。随着Moebius的诞生,开发者们迎来了一个里程碑式的变革,这是一套专为PHP 8.1设计的纯净协程解决方案,它彻底颠覆了我们对于并发编程的传统认知。 项目介绍 想象一下,无需复杂的回调地狱,也不再被Promise链束缚,仅仅通过PHP本色出演,就能实现高效的异...

gitblog_00594的博客 732

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

php的协程

在php中,实现协程主要由两种方式 1.yield生成器的实现 2.swoole扩展实现 协程不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。 一个程序可以包含多个协程,可以对比与一个进程包含多个线程,因而下面我们来比较协程和线程。 我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程 由当前协程来控制 协程执行顺序 首先,我们来看一个原生php代码: <?php function task

读万卷书,行万里路 2715

php协程(Coroutine)学习笔记

PHP5.5中加入了一个新特性—迭代生成器和协程。一. 什么是协程(Coroutine)?在协程出现之前,要实现多任务并发,在无OS(操作系统)时代,可以使用状态机的思想对多任务进行拆解,在单进程环境中运行多任务,但是这种模式下需要开发者对每个任务有清晰的了解,也要开发者自行开发与任务相关功能(如任务间的通讯)。后来出现了OS(操作系统),咱们就开始使用OS提供的进程和线程功能来轻易实现多任务了。在

Gavin_new的博客 7257

php8加入swoole,PHP8确认支持JIT,加上Swoole后快到飞起

标签:带来高并发业务kafka架构百度地图写入扩展引入自 1994 年 PHP诞生 以来, PHP语言经历了许多改进,其中性能是开发人员在评估新版本时考虑的主要标准之一。之前的版本暂且先不提,咱们可以先来唠唠目前使用的PHP7.3版本,大家都知道 PHP 7 发布的时候号称比 PHP5.6 快两倍,那PHP7.3的性能如何呢?Phoronix 在 P...

weixin_42510924的博客 807

php 协程 有什么用,php协程是什么

协程要求当前正在运行的任务自动把控制权回传给调度器,这样就可以继续运行其他任务。这与抢占式的多任务正好相反, 抢占多任务的调度器可以强制中断正在运行的任务, 不管它自己有没有意愿。如果仅依靠程序自动交出控制的话,那么一些恶意程序将会很容易占用全部 CPU 时间而不与其他任务共享。协程的调度是由协程自身主动让出控制权到外层调度器实现的回到刚才生成器实现 xrange 函数的例子,整个执行过程的交替可...

weixin_33355665的博客 400

PHP协程程序

协程 协程与子进程(某个主程序的一部分代码)一样,协程也是一种程序组件。 协程(coroutine)不是进程或线程,其执行过程更类似于子进程,或者说不带返回值的函数调用 对比 一个程序可以包含多个协程,对比一个进程可以包含多个线程,多个线程相对独立,有自己的上下文,切换受系统控制;协程也相对独立,有自己的上下文,但切换由自己控制,从当前协程切换到其它协程由当前协程来控制。 协程的支持 Lua5 Python的yield关键字 PHP5.5的yield关键字 生成器使用 迭代器(Iterator) 可在内部迭

weixin_39218464的博客 741

PHP 协程

协程,又称微线程,纤程。英文名Coroutine。 PHP 官方文档的解释: 生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。 生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组, 那会使你的内存达到上限,或者会占据可观的处理时间。相反,你可以写一个生成器函数,就像一个普通的自定

HAOWENQI008的博客 529

php协程 多线程,PHP中协程实现学习笔记

第一部分 什么是协程(Coroutine)一、概念0、先来看看Wikipedia Coroutine上的定义(Wikipedia协程中文定义):Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to...

weixin_32311541的博客 239

php-协程的实现

协程的实现参考: http://www.laruence.com/2015/05/28/3038.html https://segmentfault.com/a/1190000012457145?utm_source=tuicool&utm_medium=referral 既然协程性能这么高,那为什么使用的还是很少呢,还是其使用场景不是很多,加上协程还是有点不好理解。 协程的作用是实施任务...

猛犸象 1119
上一篇: C# 调用方信息特性全解析(从原理到高性能日志系统设计)
下一篇: PHP 7.3空合并赋值数组技巧曝光(90%程序员忽略的高效写法)
QuickProceed
博客等级 码龄1年 149粉丝 2008原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值