您的位置:首页 > 游戏 > 手游 > 平面设计都学什么_温州日报瓯网_李守洪_市场推广seo职位描述

平面设计都学什么_温州日报瓯网_李守洪_市场推广seo职位描述

2025/4/26 11:24:12 来源:https://blog.csdn.net/2301_76423513/article/details/146417900  浏览:    关键词:平面设计都学什么_温州日报瓯网_李守洪_市场推广seo职位描述
平面设计都学什么_温州日报瓯网_李守洪_市场推广seo职位描述

基于I.MX6ULL.MINI开发板

  • 标准I/O库
  • 链接
  • 目录
  • 删除文件
  • 正则表达式
  • 系统标识
  • 时间
  • 堆内存
  • 信号
    • 标准信号
  • 进程
  • 进程组
  • 进程间通信
  • 线程
    • 互斥锁
    • 线程安全

本文章是入门篇的概念,有点零散,后续需要补充复习

**inode(索引节点)**是 Linux 和 Unix 文件系统(如ext4、xfs)中的数据结构,用于存储文件的元信息(metadata),而不存储文件内容或文件名。
inode 存储的信息
文件类型(普通文件、目录、符号链接等)
文件权限(rwx)
所有者(UID)和组(GID)
文件大小
创建、修改、访问时间(ctime、mtime、atime)
链接计数(有多少硬链接指向这个文件)
数据块指针(指向文件数据所在的磁盘块)
inode 不包含的信息
文件名:文件名存储在目录(dirent 结构)中,并通过 inode 号与 inode 关联。

在测试函数strerror
用命令gcc -o test test.c编译下面的代码时报错

[/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/14/…/…/…/x86_64-linux-gnu/Scrt1.o: in function ’_start‘: (.text+0x1b): undefined reference to `main’collect2: error: ld returned 1 exit status

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>int main(void)
{int fd;/* 打开文件 */fd = open("./test_file", O_RDONLY);if (-1 == fd) {printf("Error: %s\n", strerror(errno));return -1;}close(fd);return 0;
}

原因是没有使用共享库
使用命令gcc -shared -g -o test test.c就能编译成功了

命令du -h 文件名,可以查看文件实际占用存储块的大小

函数menset,给数组赋值

void *memset(void *str, int c, size_t n)

同一个进程中多次调用 open 函数打开同一个文件,各数据结构之间的关系如下图所示
在这里插入图片描述

不同进程中分别使用 open 函数打开同一个文件,其数据结构关系图如下所示:
在这里插入图片描述

同一个进程中通过 dup(dup2)函数对文件描述符进行复制,其数据结构关系如下图所示:

在这里插入图片描述

标准I/O库

函数FILE *fopen(const char *path, const char *mode);
参数mode取值如下

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

定义一个用于存放数据的 buf,起始地址以 4096 字节进行对齐
static char buf[8192] __attribute((aligned (4096)));

__attribute 是 gcc 支持的一种机制(也可以写成__attribute __) ,可用于设置函数属性、变量属性以及类型属性等

fd = open("./test_file", O_WRONLY | O_CREAT | O_TRUNC, 0664);

0664 是文件权限(mode),用于指定新创建文件的访问权限。在 open() 调用中,它只有在 O_CREAT 标志存在时才生效。

在这里插入图片描述

查看文件类型方法
命令statls
stat可以看到很详细的信息
ls -l通过符号表示文件的类型
在这里插入图片描述

Linux 系统中,可将硬件设备分为字符设备和块设备,所以就有了字符设备文件和块设备文件两种文件类型。虽然有设备文件,但是设备文件并不对应磁盘上的一个文件,也就是说设备文件并不存在于磁盘中,而是由文件系统虚拟出来的,一般是由内存来维护,当系统关机时,设备文件都会消失;字符设备文件一般存放在Linux 系统/dev/目录下,所以 /dev 也称为虚拟文件系统 devfs

Ubuntu 发行版对 ls 命令做了别名处理,执行 ls命令的时候携带了一些选项,而这些选项会访问文件的一些信息,所以导致出现"权限不够"问题,这也说明,只拥有读权限、是没法访问目录下的文件的;为了确保使用的是ls 命令本身,执行时需要给出路径的完整路径/bin/ls

链接

硬链接:ln 源文件 链接文件
软链接:ln -s 源文件 链接文件

硬链接:int link(const char *oldpath, const char *newpath);
软链接:int symlink(const char *target, const char *linkpath);

取出软链接文件中存储的路径信息:ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);

目录

创建目录:int mkdir(const char *pathname, mode_t mode);
删除目录:int rmdir(const char *pathname);
打开目录:DIR *opendir(const char *name);
读取目录:struct dirent *readdir(DIR *dirp);void rewinddir(DIR *dirp);
关闭目录:int closedir(DIR *dirp);

获取进程当前的工作目录:char *getcwd(char *buf, size_t size);
修改当前的工作目录:int chdir(const char *path);int fchdir(int fd);

删除文件

系统调用:uint unlink(const char *pathname);
C库函数:int remove(const char *pathname);

正则表达式

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include <string.h>
int main(int argc, char *argv[])
{regmatch_t pmatch = {0};regex_t reg;char errbuf[64];int ret;char *sptr;int length;int nmatch; //最多匹配出的结果/*作用:检查命令行参数数量是否正确(应有 3 个参数)。argv[1]:正则表达式argv[2]:待匹配字符串argv[3]:最大匹配次数如果参数不符合要求,程序退出。*/if (4 != argc) {/*********************************** 执行程序时需要传入两个参数:* arg1: 正则表达式* arg2: 待测试的字符串* arg3: 最多匹配出多少个结果**********************************/fprintf(stderr, "usage: %s <regex> <string> <nmatch>\n", argv[0]);exit(0);}/* 编译正则表达式regcomp(&reg, argv[1], REG_EXTENDED) 编译正则表达式如果编译失败,使用 regerror() 输出错误信息,并退出。*/if(ret = regcomp(&reg, argv[1], REG_EXTENDED)) {regerror(ret, &reg, errbuf, sizeof(errbuf));fprintf(stderr, "regcomp error: %s\n", errbuf);exit(0);}/* 赋值操作sptr 指向待匹配的字符串length 记录 sptr 长度nmatch 由 argv[3] 转换为整数,代表最多匹配多少次*/sptr = argv[2]; //待测试的字符串length = strlen(argv[2]);//获取字符串长度nmatch = atoi(argv[3]); //获取最大匹配数/* 匹配正则表达式循环 nmatch 次,每次尝试匹配正则regexec(&reg, sptr, 1, &pmatch, 0) 执行正则匹配pmatch.rm_so:匹配子串的起始位置pmatch.rm_eo:匹配子串的结束位置如果 regexec() 失败(无匹配),打印错误并跳转到 out 释放正则资源。*/for (int j = 0; j < nmatch; j++) {char temp_str[100];/* 调用 regexec 匹配正则表达式 */if(ret = regexec(&reg, sptr, 1, &pmatch, 0)) {regerror(ret, &reg, errbuf, sizeof(errbuf));fprintf(stderr, "regexec error: %s\n", errbuf);goto out;}if(-1 != pmatch.rm_so) {//pmatch.rm_so == pmatch.rm_eo 时,匹配的是 空字符串,需要跳过 1 个字符,防止死循环。if (pmatch.rm_so == pmatch.rm_eo) {//空字符串sptr += 1;length -= 1;printf("\n"); //打印出空字符串if (0 >= length)//如果已经移动到字符串末尾、则退出break;continue; //从 for 循环开始执行}//memcpy() 提取 sptr 中匹配的子串,并存入 temp_str//printf("%s\n", temp_str); 打印匹配结果memset(temp_str, 0x00, sizeof(temp_str));//清零缓冲区memcpy(temp_str, sptr + pmatch.rm_so,pmatch.rm_eo - pmatch.rm_so);//将匹配出来的子字符串拷贝到缓冲区printf("%s\n", temp_str); //打印字符串//跳过当前匹配的部分,继续匹配剩余字符串//避免死循环(如果 length <= 0,停止匹配)sptr += pmatch.rm_eo;length -= pmatch.rm_eo;if (0 >= length)break;}}/* 释放正则表达式 */
out:regfree(&reg);exit(0);}
./regex_program "a[0-9]+" "abc a12 b34 a56 a78 xyz" 3 //代码执行
//匹配 a 后跟随 至少一个数字
//只匹配 最多 3 次(nmatch=3)
/*
结果
a12
a56
a78
*/

系统标识

struct utsname {char sysname[]; /* 当前操作系统的名称 */char nodename[]; /* 网络上的名称(主机名) */char release[]; /* 操作系统内核版本 */char version[]; /* 操作系统发行版本 */char machine[]; /* 硬件架构类型 */#ifdef _GNU_SOURCEchar domainname[];/* 当前域名 */#endif
};
struct sysinfo {long uptime; /* 自系统启动之后所经过的时间(以秒为单位) */unsigned long loads[3]; /* 1, 5, and 15 minute load averages */unsigned long totalram; /* 总的可用内存大小 */unsigned long freeram; /* 还未被使用的内存大小 */unsigned long sharedram; /* Amount of shared memory */unsigned long bufferram; /* Memory used by buffers */unsigned long totalswap; /* Total swap space size */unsigned long freeswap; /* swap space still available */unsigned short procs; /* 系统当前进程数量 */unsigned long totalhigh; /* Total high memory size */unsigned long freehigh; /* Available high memory size */unsigned int mem_unit; /* 内存单元大小(以字节为单位) */char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding to 64 bytes */
};

时间

GMT 时间
GMT(Greenwich Mean Time)中文全称是格林威治标准时间,这个时间系统的概念在 1884 年被确立,由英国伦敦的格林威治皇家天文台计算并维护,并在之后的几十年向欧陆其它国家扩散。
由于从 19 实际开始,因为世界各国往来频繁,而欧洲大陆、美洲大陆以及亚洲大陆都有各自的时区,所以为了避免时间混乱,1884 年,各国代表在美国华盛顿召开国际大会,通过协议选出英国伦敦的格林威治作为全球时间的中心点,决定以通过格林威治的子午线作为划分东西两半球的经线零度线(本初子午线、零度经线),由此格林威治标准时间因而诞生!
所以 GMT 时间就是英国格林威治当地时间,也就是零时区(中时区)所在时间,譬如 GMT 12:00 就是指英国伦敦的格林威治皇家天文台当地的中午 12:00,与我国的标准时间北京时间(东八区)相差 8 个小时,即早八个小时,所以 GMT 12:00 对应的北京时间是 20:00。

UTC 时间
UTC(Coordinated Universal Time)指的是世界协调时间(又称世界标准时间、世界统一时间),是经过平均太阳时(以格林威治时间 GMT 为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC 比 GMT 来得更加精准

查看UTC时间:date -u

jiffies 是内核中定义的一个全局变量,内核使用 jiffies 来记录系统从启动以来的系统节拍数,所以这个变量用来记录以系统节拍时间为单位的时间长度,Linux 内核在编译配置时定义了一个节拍时间,使用节拍率(一秒钟多少个节拍数)来表示

在这里插入图片描述

堆内存

申请堆内存有malloc()calloc()

#define MALLOC_MEM_SIZE (1 * 1024 * 1024)
int main(int argc, char *argv[])
{//声明一个字符指针 base,并初始化为 NULLchar *base = NULL;/* 申请堆内存 *///malloc(MALLOC_MEM_SIZE) 从堆上申请 MALLOC_MEM_SIZE 字节的内存。//malloc() 返回 void* 指针,需要强制转换为 char*base = (char *)malloc(MALLOC_MEM_SIZE);if (NULL == base) {printf("malloc error\n");exit(-1);}/* 初始化申请到的堆内存 */memset(base, 0x0, MALLOC_MEM_SIZE);/* 使用内存 *//* ...... *//* 释放内存 */free(base);return 0}

**calloc()**在堆中动态地分配 nmemb 个长度为 size 的连续空间,并将每一个字节都初始化为 0
calloc()与 malloc()的一个重要区别是:calloc()在动态分配完内存后,自动初始化该内存空间为零,而malloc()不初始化,里边数据是未知的垃圾数据。

一下的两种写法是等价的

// calloc()分配内存空间并初始化
char *buf1 = (char *)calloc(10, 2);// malloc()分配内存空间并用 memset()初始化
char *buf2 = (char *)malloc(10 * 2);
memset(buf2, 0, 20);

信号

标准信号

在这里插入图片描述

核心转储文件(Core Dump)是什么?
核心转储(Core Dump)是 程序崩溃时,操作系统 自动保存的内存快照。它包含了进程在崩溃时的 内存数据、CPU 寄存器、堆栈信息、打开的文件描述符 等信息,帮助开发者 调试程序崩溃的原因。
核心转储文件通常命名为 core 或 core.pid(pid 为进程 ID),默认生成在程序的工作目录。
核心转储文件的作用
1.调试崩溃原因
查看程序崩溃时的调用栈、变量值、内存状态等信息。
2.分析段错误(Segmentation Fault, SIGSEGV)
访问非法地址时,操作系统会触发 SIGSEGV,并生成 core dump。
3.检查死锁、资源泄漏
通过分析核心转储文件,检查线程死锁、文件描述符泄漏等问题。
4.重现难以复现的 Bug
记录程序崩溃时的完整状态,方便后续分析。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

忽略信号(Ignore Signal)
进程接收到信号后,可以选择不处理,相当于信号被丢弃。

捕获信号(Catch Signal)
进程可以定义自定义信号处理函数,在收到信号时执行特定操作,而不是采用默认行为。

进程

在这里插入图片描述

进程组

setpgid(0,pgid) == setpgid(getpgrp(),pgid)
setpgid(pid,0) == setpgid(pid,pid)
setpgrp() == setpgid(0.0) == etpgid(getpgrp(),getpgrp())

./testapp & 中的 & 用于 将命令放入后台运行,使其在 后台执行,而不阻塞当前终端。
输出示例:[1] 12345
[1]: 作业编号(Job ID),可以用 jobs 命令查看。
12345:进程 ID(PID),可以用 kill 12345 终止该进程。

进程间通信

在这里插入图片描述

UNIX 是一种 多用户、多任务 的 操作系统,最早由 AT&T 贝尔实验室 在 1969 年开发。它广泛应用于服务器、工作站和嵌入式系统,以 稳定性、高效性和安全性 著称。

管道: 把一个进程连接到另一个进程的数据流称为管道,管道(Pipe)是一种进程间通信(IPC,Inter-Process Communication) 机制,允许一个进程的输出作为另一个进程的输入,常用于数据流式处理。

在这里插入图片描述

线程

线程处于分离状态(Detached State)意味着该线程的 资源在结束时会自动释放,而 不需要其他线程(如主线程)显式 join() 等待它结束。

互斥锁

Mutex(互斥锁) 是一种线程同步机制,用于防止多个线程同时访问共享资源,避免数据竞争和不一致。

在这里插入图片描述

在这里插入图片描述

执行流(Execution Flow)指的是 程序运行时指令的执行顺序,即 代码如何被逐步执行。它决定了程序如何处理 函数调用、条件判断、循环和多线程等,一个线程就是一条执行流

线程安全

在这里插入图片描述

信号处理函数的执行流(Signal Handling Execution Flow)
在 UNIX/Linux 系统中,信号(Signal)是一种 异步事件,可以在 程序执行的任何时刻打断正常的执行流,然后跳转到 信号处理函数(Signal Handler) 执行特定操作。

//pthread_create() 用于创建一个新线程
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

在这里插入图片描述

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com