35. 【C语言】与操作系统对话:系统调用与文件底层 I/O

Python程序I/O性能优化:系统调用与缓冲技术解析 程序I/O操作是现代计算机系统中的基础技术概念,其性能差异主要源于用户态与内核态的切换机制。当应用程序执行文件写入或终端输出时,必须通过系统调用进入内核态,这个过程涉及上下文切换和权限检查,会产生显著的性能开销。在工程实践中,合理使用缓冲技术和批量处理策略能有效减少系统调用次数,这是提升I/O密集型应用性能的关键。特别是在Python等高级语言开发中,理解print函数与文件写入的底层差异尤为重要。通过实测对比可见,终端输出比文件写入慢2-3倍,而无I/O操作的程序速度最快。这些优化思路在大数据处理、日志系 阅读详情

前面第二十四、二十五篇,我们学过了 C 标准库的文件操作——fopen、fprintf、fread、fwrite。它们用起来很方便,有缓冲、有格式化。但你是否想过:这些函数底层是怎么把数据写到磁盘的?FILE * 到底包装了什么?

今天我们往下沉一层,直接和操作系统内核对话:学习 系统调用(System Call) 与 文件底层 I/O。这是 C 程序员从“应用层”迈向“系统层”的关键一步。理解它们,你才能真正搞懂 I/O 的性能差异从何而来,也能开始写更贴近硬件的程序。


一、什么是系统调用?

操作系统掌管着所有硬件资源:CPU、内存、磁盘、网络。普通程序不能直接访问硬件(否则一个 bug 就能毁掉整个系统),必须通过操作系统提供的“服务窗口”来请求资源。这个窗口就是系统调用。

可以把系统调用想象成“政府办事窗口”:

  • 你(用户程序)填好申请表(设置参数),
  • 递进窗口(触发系统调用),
  • 操作系统内核审核并执行(访问硬件),
  • 把结果返回给你。

C 标准库中的很多函数(如 printf、malloc、fopen)内部最终都会调用系统调用。但我们也可以绕过标准库的包装,直接使用系统调用:这就是 Unix/Linux 下的 POSIX 系统调用,如 open、read、write、close。

注意:这些函数在 Windows 上也存在对应版本(如 CreateFile、ReadFile),但名称和行为不同。本文以 POSIX(Linux/macOS)为例。Windows 用户可以在 WSL 中跟随。


二、文件描述符:内核眼中的“文件身份证”

标准 C 库用 FILE * 表示文件。而系统调用用一个整数来表示打开的文件:这个整数叫文件描述符(File Descriptor,FD)。

每个进程启动时,操作系统自动打开三个标准文件描述符:

文件描述符符号常量含义
0STDIN_FILENO标准输入(键盘)
1STDOUT_FILENO标准输出(屏幕)
2STDERR_FILENO标准错误(屏幕)

这三个常量定义在 <unistd.h> 中。你每天用的 printf,底层就是向文件描述符 1 写入数据;scanf 就是从 0 读取数据。

新打开的文件会被分配一个当前未使用的最小整数作为描述符。比如你打开一个文件,它可能得到 3。


三、底层 I/O 函数:open、read、write、close

使用这些函数需要包含头文件:

#include <unistd.h>    // read, write, close
#include <fcntl.h>     // open 的标志
#include <sys/types.h> // 一些类型定义(有时需要)
#include <sys/stat.h>  // 文件权限标志

1. open:打开文件

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
  • pathname:文件路径。
  • flags:打开标志,控制读写行为,可以用 | 组合多个。
  • mode:若创建新文件,指定其权限(如 0644)。
  • 返回值:成功返回文件描述符(≥0),失败返回 -1 并设置 errno。

常用 flags:

标志含义
O_RDONLY只读
O_WRONLY只写
O_RDWR读写
O_CREAT文件不存在则创建(需同时传 mode)
O_TRUNC打开时清空文件内容
O_APPEND每次写入自动追加到末尾

示例:打开(或创建)一个文件用于写入:

int fd = open("data.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
    perror("open 失败");
    return 1;
}

2. write:写数据

ssize_t write(int fd, const void *buf, size_t count);
  • fd:文件描述符。
  • buf:要写入的数据缓冲区。
  • count:期望写入的字节数。
  • 返回值:实际写入的字节数。返回 -1 表示出错。
const char *msg = "Hello, system call!\n";
ssize_t bytes_written = write(fd, msg, strlen(msg));
if (bytes_written == -1) {
    perror("write 失败");
}

注意:write 不一定能一次性写完所有字节(尤其在网络 I/O 或磁盘满时),严谨的写法需要循环写入。

3. read:读数据

ssize_t read(int fd, void *buf, size_t count);
  • buf:存放读取内容的缓冲区。
  • count:最多读取的字节数。
  • 返回值:实际读取的字节数。返回 0 表示读到文件末尾;-1 表示出错。
char buffer[100];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
if (bytes_read > 0) {
    buffer[bytes_read] = '\0';   // 手动加 '\0'
    printf("读到: %s\n", buffer);
}

read 不会自动在末尾加 '\0',如果要当字符串用,必须自己加。

4. close:关闭文件

int close(int fd);

关闭文件描述符,释放内核资源。成功返回 0,失败返回 -1。


四、完整示例:用系统调用复制文件

把前面的知识组合起来,实现一个简单的文件复制程序,不用任何标准 C 文件函数。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>

#define BUFFER_SIZE 4096

int main(int argc, char *argv[]) {
    if (argc != 3) {
        const char *usage = "用法: ./copy <源文件> <目标文件>\n";
        write(STDERR_FILENO, usage, strlen(usage));
        return 1;
    }

    int src_fd = open(argv[1], O_RDONLY);
    if (src_fd == -1) {
        perror("打开源文件失败");
        return 1;
    }

    int dst_fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (dst_fd == -1) {
        perror("打开目标文件失败");
        close(src_fd);
        return 1;
    }

    char buffer[BUFFER_SIZE];
    ssize_t bytes_read;
    while ((bytes_read = read(src_fd, buffer, BUFFER_SIZE)) > 0) {
        ssize_t bytes_written = write(dst_fd, buffer, bytes_read);
        if (bytes_written != bytes_read) {
            perror("写入失败");
            close(src_fd);
            close(dst_fd);
            return 1;
        }
    }

    if (bytes_read == -1) {
        perror("读取失败");
        close(src_fd);
        close(dst_fd);
        return 1;
    }

    return 0;
}

编译运行:

gcc -o copy copy.c
./copy source.txt dest.txt

你会发现,这和标准库的 fopen/fread 风格截然不同——没有 FILE *,只有整数文件描述符;没有格式化,只有原始字节流。这就是底层。


五、标准 I/O vs 系统 I/O:缓冲区的秘密

你可能想问:既然标准库最终也是调用系统调用,那 fprintf 和 write 有什么区别?答案是:缓冲区。

标准 I/O (FILE*)系统 I/O (fd)
缓冲用户态缓冲(默认有)无用户态缓冲
调用频率攒够数据再系统调用每次都是系统调用
适合场景小数据量、格式化文本大数据块、精确控制、设备 I/O

标准 I/O 在用户态维护了一个缓冲区。你调用 fprintf,数据先写进缓冲区;缓冲区满了(或遇到换行、调用 fflush)才触发一次系统调用 write,真正交给内核。这极大地减少了系统调用的次数——而系统调用本身是昂贵的(涉及用户态/内核态切换)。

系统 I/O 没有这个缓冲。你每调用一次 write,就立刻切到内核态执行一次系统调用。如果你逐字节写 1MB 数据,就是 100 万次系统调用,慢得难以忍受。但如果每次写 4KB 或更大的块,效率可以很高。

// 高效:每次写大块
write(fd, buffer, 4096);

// 极低效:逐字节写
for (int i = 0; i < n; i++) {
    write(fd, &data[i], 1);   // 每次一个系统调用!
}

特殊情况:标准输出

标准 C 的 stdout 默认是行缓冲的——遇到换行符 \n 会刷新缓冲区。如果你混用 printf 和 write(STDOUT_FILENO, ...),可能会发现输出顺序不对,因为两者使用了不同的缓冲机制。解决方法是统一用一种,或在混用前调用 fflush(stdout)。

何时直接使用系统 I/O?

  • 你需要精确控制每次写入的大小、时机(如写入网络包、设备寄存器)。
  • 你操作的是文件描述符(如管道、socket、设备文件),而标准 C 没有封装它。
  • 你已经在做大量数据的整块读写,且想避免用户态缓冲的额外拷贝。

日常文本文件的读写用标准 I/O 就足够了,更安全、更方便。


六、errno 与错误处理

系统调用失败时返回 -1 或 NULL,同时设置全局变量 errno,里面存着具体的错误码。perror 可以根据 errno 打印对应的错误信息,也可以手动检查:

#include <errno.h>
#include <string.h>

int fd = open("nonexist.txt", O_RDONLY);
if (fd == -1) {
    printf("错误码: %d\n", errno);
    printf("错误信息: %s\n", strerror(errno));
}

常见错误码:

  • ENOENT:文件不存在
  • EACCES:权限不足
  • EMFILE:进程打开的文件描述符已达上限
  • ENOSPC:磁盘空间不足

系统编程中,检查每一个系统调用的返回值并恰当处理错误,是基本素养。


七、小结

今天你从标准 C 库往下沉了一层,直接触碰了操作系统内核的接口:

  • 系统调用是用户程序请求内核服务的唯一方式。
  • 文件描述符是内核管理打开文件的整数 ID,标准输入/输出/错误分别对应 0、1、2。
  • open/read/write/close 是底层 I/O 的核心系统调用,操作的是原始字节流。
  • 标准 I/O vs 系统 I/O 的关键区别在于用户态缓冲区:标准 I/O 用它减少系统调用次数,提高小数据量场景的效率;系统 I/O 无缓冲,适合大数据块或精确控制场景。
  • 系统调用出错时设置 errno,通过 perror 或 strerror 获取信息。

理解系统调用,你就理解了 C 程序是如何与整个计算机系统交互的。这也是嵌入式开发、网络编程、操作系统开发的基础——在那些领域,你几乎天天和文件描述符打交道。

下一篇文章,我们将利用这些知识,探索 C 语言中静态库与动态库的制作与使用:把代码打包成 .a 和 .so,让你的模块可以被其他程序共享和复用。这是从“写代码”走向“发布软件”的必经之路。


课后小练习

  1. 用系统调用实现一个简易的 cat 程序:接收文件名作为命令行参数,将文件内容输出到标准输出。如果文件名没传,则从标准输入读取并输出(相当于 cat 不带参数的行为)。
  2. 用 open、read、write 实现一个函数 int file_copy(const char *src, const char *dst),在内部处理所有错误,返回 0 表示成功,-1 表示失败。对比它与标准 C 的 fread/fwrite 实现的差异。
  3. 混用 printf 和 write(STDOUT_FILENO, ...),分别观察在换行和不换行时输出顺序的变化。调用 fflush(stdout) 后再试一次,理解缓冲机制。
  4. (小挑战)写一个程序,在文件末尾追加当前的时间戳(time() 获取)。要求使用 O_APPEND 标志,并验证每次运行后文件新内容确实在末尾。

我们下期见!

💡获取本系列示例代码请访问 GitCode 仓库。

epoll与io_uring深度对比:I/O多路复用与真正异步I/O的本质差异 I/O模型是操作系统与应用程序协同处理数据流动的基础机制。从阻塞I/O到非阻塞轮询,再到I/O多路复用(如epoll)和真正异步I/O(如io_uring),其演进核心在于‘等待成本’的转移路径:由线程挂起、忙等、事件驱动,最终走向内核全权接管与零拷贝完成。epoll通过红黑树+就绪链表实现高效事件通知,已成为高并发网络服务的事实标准;而io_uring依托共享内存环形缓冲区与内核专用线程,突破系统调用瓶颈,支撑存储与网络I/O的极致性能。二者并非替代关系,而是适配不同负载特征——epoll胜在确定性低延迟 阅读详情

相关推荐

I/O多路复用与异步I/O本质区别:从epoll到io_uring的演进逻辑

I/O模型是操作系统与应用程序交互的核心机制,涉及阻塞、非阻塞、I/O多路复用和异步I/O四大范式。其底层原理围绕数据拷贝路径、上下文切换开销及事件通知方式展开:传统阻塞I/O受限于线程膨胀,非阻塞需配合事件通知才能实用;I/O多路复用(如epoll)通过内核就绪通知实现单线程高并发管理,属同步语义但支撑异步编程模型;而真正异步I/O(如io_uring)则通过共享内存环形队列、零拷贝提交与完成,消除系统调用与上下文切换,达成数据直通设备。技术价值在于突破C10K/C100K瓶颈,适用于Web服务器、实时交

diaojin6880的博客 401

C语言与操作系统交互探秘

在 C语言中,系统调用是用户程序与操作系统内核交互的桥梁。

jiaworld的博客 1009

14、缓冲文件I/O:简化文件操作的艺术

本博文深入探讨了C语言中缓冲文件I/O的操作与优化技巧,详细解析了printf函数的使用方法和主要转换字符的应用场景。同时,通过实际代码示例展示了如何利用缓冲机制提高文件读写的效率,并介绍了文件操作中的高级功能及错误处理方法,帮助开发者编写高效、稳定的程序。

docker8compose的博客 203

Linux中的基础I/O

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录系列文章目录前言一、pandas是什么?二、系统文件I/01.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下

wzd547191555的博客 1996

听说Zynq-I/O详细信息

概述ZYNQ 是由两个主要部分组成的:一个由双核 ARM Cortex-A9 为核心构成的处理系统(PS,Processing System),和一个等价于一片FPGA的可编程逻辑(PL...

不只会拍照的程序猿 1467

C语言实现端口扫描器:TCP握手、非阻塞I/O与批量探测实践

网络编程中,端口扫描是服务发现与安全审计的基础技术。TCP三次握手协议决定了连接建立的成功与否,而C语言通过socket接口可以直接操控这一过程。非阻塞I/O配合select多路复用,能有效控制超时时间并提升批量探测效率。基于资源限制的合理管理,可以构建稳定的扫描工具。该技术适用于课程设计、受控网络服务验证及运维排障场景。本文以C语言逐步实现一个可调参数的端口扫描器,涵盖状态判定、批量调度与结果验证,帮助读者从原理上理解连接语义。

weixin_30225755的博客 92

【文本I/O和二进制I/O】

为了更直观地理解它们的区别和联系,可以参考下面的流程图:fill:#333;important;important;fill:none;color:#333;color:#333;important;fill:none;fill:#333;height:1em;important;important;important;important;important;important;important;important;important;important;important;important;

Beaman的博客 644

CentOS7下用FreeRADIUS+AD实现802.1X认证完整指南(附华为交换机配置)

本文提供了在CentOS 7系统上部署FreeRADIUS并与Windows Active Directory集成,以实现企业级802.1X网络认证的完整实战指南。内容涵盖从架构原理、服务器配置(包括Kerberos、Samba Winbind集成)、FreeRADIUS核心设置与AD联动,到华为交换机的详细配置步骤。重点解决了生产环境中常见的高可用、动态VLAN下发及深度排错问题,为企业构建集中、安全的网络准入控制体系提供了经过验证的解决方案。

weixin_29273849的博客 405

linux系统编程之文件与I/O(一):文件的打开关闭

转自:https://blog.csdn.net/Simba888888/article/details/8917854 一、文件描述符 对于Linux而言,所有对设备或文件的操作都是通过文件描述符进行的。当打开或者创建一个文件的时候,内核向进程返回一个文件描述符(非负整数)。后续对文件的操作只需通过该文件描述符,内核记录有关这个打开文件的信息(file结构体)。 一个进程启动时,默认打开了3...

HappyMrSpring 278

倍福TwinCAT3 OPC UA配置全流程:从安装到无密码访问(附常见问题解决)

本文提供了倍福TwinCAT3 OPC UA配置的完整实战指南,重点讲解如何实现无密码游客访问。从软件安装、授权配置、服务器初始化到深度排错,详细解析了配置流程中的关键步骤与常见陷阱,帮助工程师高效打通PLC与上位系统的数据通讯通道。

vulkan6gpu的博客 471

SIwave仿真手册——信号完整性仿真之S参数的提取(二)

上一篇简单了讲述了软件的各个操作界面,本次博客更新关于的仿真,因为第二章完整的内容比较多,所以分成好几篇博客进行分享。

luohuo9844的博客 1万+

Linux I/O编程

一、实验目的: 练习用UNIX I/O进行文件读写的编程方法,用UNIX I/O函数管理文本信息、二进制数据、结构体数据,掌握UNIX I/O的基本编程方法。练习测时函数使用,通过测量UNIX I/O函数运行时间,建立UNIX I/O API函数基本开销的概念。 二、实验内容与要求: 先创建用户家目录下创建文件名为“姓名+学号+04”的子目录,作为本次实验目录,本次实验的所有代码都放到该目录...

qq_40165417的博客 4256

单片机OTA升级:Bootloader如何多重校验保障APP完整性?

本文详细介绍了单片机OTA升级中Bootloader如何通过CRC校验、数字签名、版本比对和存储位置检查等多重校验机制保障APP完整性。CRC校验作为快速检测数据完整性的核心手段,结合其他安全措施有效防止设备变砖和安全漏洞,确保远程升级的可靠性。

l3m4n的博客 981

从Windows API调用到硬盘灯闪烁:手把手拆解一次文件读写背后的完整I/O旅程

本文深入解析Windows系统中文件读写操作的完整I/O旅程,从用户层API调用到硬件层面的硬盘灯闪烁。详细拆解了软件层次结构中的设备驱动程序、中断处理程序等关键组件,揭示了I/O操作背后的复杂协作机制,为开发者提供全面的技术视角。

weixin_30736301的博客 488

别再手动找触点了!EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战

本文详细解析EPLAN线圈触点映像的3种显示方式与F键/Ctrl+B快捷键实战技巧,帮助电气设计工程师提升图纸操作效率。通过精简编号、路径栏显示和元件旁可视化三种模式的应用场景对比,结合快捷键肌肉记忆训练法,实现触点快速定位与管理,大幅减少手动查找时间。

weixin_42522964的博客 481

9篇1章1节:中国居民健康与营养调查(CHNS)数据库的官网解析和数据下载(2026年版)

在探讨中国社会经济转型与人口健康变迁的学术领域中,中国健康与营养调查(CHNS) 是一个无法绕过的权威数据库。本文将带你深入了解CHNS的项目背景、庞大的数据体系,以及如何通过这两个核心网站获取关键的家庭、个人及社区层面的研究数据。

MD Code 1690

APUE知识点记录 【三】标准I/O库

通过文件I/O读写文件时,每次操作都会执行相关系统调用。这样处理的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销,标准I/O可以看成是在文件I/O的基础上封装了缓冲机制。先读写缓冲区,必要时再访问实际文件,从而减少了系统调用的次数。 int fflush(FILE *fp);//如若fp是NULL,则次函数将导致所有输出流被冲洗。 1. 流与FILE对象 标准I/O库的所有操作都是围...

RaKiRaKiRa的博客 347

深度学习工具包 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")

第五章:标准I/O库

本章用于解析C语言标准I/O库,之所以在UNIX类系统的编程中会介绍C语言标准库,主要是因为UNIX和C之间具有密不可分的关系。 标准I/O库相比于操作系统的I/O库,具有更高的效率和可移植性,前者是因为标准I/O库提供了缓冲和块长度优化功能,后者是因为使用标准I/O库的代码不仅能在各UNIX系统上移植,也能在支持标准C的非UNIX系统上移植。 一、基本概念 流和F...

weixin_30737433的博客 84

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

JUring:高性能Java文件I/O解决方案

JUring:高性能Java文件I/O解决方案 在当今快节奏的软件世界中,文件I/O操作的高效率是提升应用性能的关键因素之一。JUring,一个基于Linux io_uring接口的高性能Java库,正是为了满足这一需求而诞生。下面,我们将详细介绍JUring的核心功能、技术分析、应用场景及其特点。 项目介绍 JUring是一个Java库,它通过Java的外部函数和内存API(Foreign Fu...

gitblog_00102的博客 1109

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

十 一、I/O操作之库函数&&系统调用的区别(三)

一、系统调用和库函数 二、两者的联系 三、两者的区别

qq_43411555的博客 481

【C语言学习笔记】35. 文件读写

上一文章我们讲解了 C 语言处理的标准输入和输出设备。本文我们将介绍 C 程序员如何创建、打开、关闭文本文件或二进制文件。 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节。C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件。本文将讲解文件管理的重要调用。

qq_62052372的博客 162
上一篇: 34. 【C语言】性能优化意识启蒙
下一篇: 36. 【C语言】程序的动态加载:静态库与动态库的制作与使用
gugucoding
博客等级 码龄140天 7粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值