第九周预习报告
文章目录
- 第九周预习报告
- 学习内容
- AI 对学习内容的总结
- 章节概述
- 内容总结
- 对知识总结的反思
- 思维导图
- 基于AI的学习
- 知识点1:系统调用
- 知识点2:进程控制
- 学习实践过程遇到的问题与解决方式
- 问题1:`fork()` 调用后,子进程和父进程同时运行导致输出混乱
- 问题2:`exec()` 调用失败,程序无法执行新程序
- 问题3:`open()` 系统调用失败,无法打开文件
- 问题4:`wait()` 调用后,父进程无法正确捕获子进程的退出状态
- 问题5:环境变量传递失败,子进程无法获取正确的环境变量
- 参考资料
第九周预习报告
学习内容
- Head First C 第9章
AI 对学习内容的总结
章节概述
- 本章主要介绍进程和系统调用的概念,学习如何在自己的代码内部使用其他程序,学会如何使用系统服务来创建和控制进程。使程序能够访问电子邮件、Web以及其他任何安装的工具。
内容总结
-
系统调用:
- 定义:系统调用是用户程序与操作系统内核之间的接口,允许用户程序请求操作系统执行特定的任务。
- 常见系统调用:
open()
:打开文件。read()
:从文件中读取数据。write()
:将数据写入文件。close()
:关闭文件。fork()
:创建一个新进程。exec()
:执行一个新程序。wait()
:等待子进程结束。exit()
:终止当前进程。
- 工作原理:当用户程序调用一个系统调用时,CPU会从用户模式切换到内核模式,内核执行相应的操作,完成后返回结果,CPU再切换回用户模式。
-
进程控制:
- 进程:进程是操作系统进行资源分配和调度的基本单位,每个进程都有自己的地址空间、文件描述符、环境变量等。
- 创建进程:
fork()
:创建一个新进程,新进程是调用进程的副本,两者几乎完全相同,但有一个唯一的区别:fork()
返回值不同。在父进程中返回子进程的PID,在子进程中返回0。
- 执行新程序:
exec()
:有一系列函数(如execl()
、execlp()
、execle()
、execv()
、execvp()
、execvpe()
),用于替换当前进程的地址空间,使其开始执行一个新程序。
- 等待子进程:
wait()
:父进程调用wait()
等待子进程结束,wait()
会阻塞父进程直到子进程结束。
- 终止进程:
exit()
:终止当前进程,可以传递一个退出状态码给父进程。
-
环境变量传递:
- 定义:环境变量是操作系统提供的一种机制,用于在进程之间传递配置信息。
- 传递方式:子进程会继承父进程的环境变量,可以通过
exec()
系列函数传递新的环境变量。
-
错误处理:
- 返回值:大多数系统调用都有一个返回值,成功时返回一个有意义的值,失败时返回一个错误码(通常是负数)。
- errno:全局变量
errno
用于存储系统调用的错误代码,可以通过strerror()
函数将错误代码转换为人类可读的字符串。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0; }
-
RSS订阅:
- 定义:RSS(Really Simple Syndication)是一种用于发布经常更新的内容的标准格式,如博客文章、新闻等。
- 实现:通过系统调用读取RSS源,解析XML数据,提取所需信息。
#include <stdio.h> #include <curl/curl.h>size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {size_t written = fwrite(ptr, size, nmemb, stream);return written; }int main() {CURL *curl;FILE *file;CURLcode res;curl_global_init(CURL_GLOBAL_DEFAULT);curl = curl_easy_init();if(curl) {file = fopen("rss_feed.xml", "wb");curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/rss.xml");curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);res = curl_easy_perform(curl);if(res != CURLE_OK) {fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));}fclose(file);curl_easy_cleanup(curl);}curl_global_cleanup();return 0; }
-
父子进程关系:
- 父子关系:通过
fork()
创建的子进程是父进程的子进程,子进程可以调用getppid()
获取父进程的PID。#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; }
- 父子关系:通过
对知识总结的反思
-
系统调用:
- 系统调用是用户程序与操作系统内核之间的桥梁,通过系统调用可以执行各种底层操作,如文件操作、进程控制等。
- 在实际编程中,需要仔细检查每个系统调用的返回值,以确保调用成功,并处理可能出现的错误。
-
进程控制:
- 进程控制是操作系统管理进程生命周期的关键部分,通过
fork()
和exec()
可以创建和执行新的进程。 - 在使用
fork()
和exec()
时,需要注意父子进程的关系,确保程序逻辑的正确性。
- 进程控制是操作系统管理进程生命周期的关键部分,通过
-
环境变量传递:
- 环境变量是进程之间传递配置信息的重要机制,子进程会继承父进程的环境变量。
- 在调用
exec()
系列函数时,可以通过参数传递新的环境变量。
-
错误处理:
- 错误处理是确保程序健壮性的关键,通过检查系统调用的返回值和使用
errno
,可以有效地处理错误。
- 错误处理是确保程序健壮性的关键,通过检查系统调用的返回值和使用
-
RSS订阅:
- RSS订阅是一个实际应用的例子,展示了如何使用系统调用和网络编程来获取和处理外部数据。
- 通过CURL库,可以方便地实现HTTP请求和数据下载。
思维导图
mindmap本周学习内容进程和系统调用章节概述系统调用定义常见系统调用openreadwritecloseforkexecwaitexit进程控制进程创建进程fork执行新程序exec等待子进程wait终止进程exit环境变量传递定义传递方式错误处理返回值errnoRSS订阅定义实现使用CURL库解析XML数据父子进程关系父子关系getppid重点内容系统调用定义常见系统调用openreadwritecloseforkexecwaitexit进程控制进程创建进程fork执行新程序exec等待子进程wait终止进程exit环境变量传递定义传递方式错误处理返回值errnoRSS订阅定义实现使用CURL库解析XML数据父子进程关系父子关系getppid
基于AI的学习
知识点1:系统调用
AI: 举一个常见的系统调用例子。
我: 打开文件是一个常见的系统调用。当程序想要读取或写入文件时,它会调用 open()
系统调用。这个调用会请求操作系统打开指定的文件,并返回一个文件描述符,程序可以使用这个文件描述符进行后续的读写操作。
AI: 系统调用 fork()
和 exec()
有什么区别?
我: fork()
和 exec()
是两个不同的系统调用,它们分别用于不同的目的。
fork()
用于创建一个新的进程。新进程是调用进程的副本,具有相同的代码段、数据段和堆栈段,但有自己的独立内存空间。fork()
返回一个值,如果返回值为0,则表示当前进程是子进程;如果返回值大于0,则表示当前进程是父进程,返回值是子进程的PID。exec()
用于在当前进程中加载并运行一个新的程序。exec()
有多个变种,如execl()
、execlp()
、execle()
、execv()
、execvp()
和execvpe()
,它们的主要区别在于参数的传递方式。调用exec()
之后,当前进程的代码段、数据段和堆栈段会被新程序的代码段、数据段和堆栈段替换。
AI: wait()
系统调用的作用是什么?
我: wait()
系统调用用于父进程等待子进程结束。父进程调用 wait()
会阻塞,直到一个子进程结束。wait()
返回子进程的PID,并且可以通过返回值和 wait()
的参数来获取子进程的退出状态。
AI: 如何处理系统调用的错误?
我: 处理系统调用的错误通常涉及以下几个步骤:
- 检查系统调用的返回值。大多数系统调用在成功时返回一个有意义的值,而在失败时返回一个错误码(通常是负数)。
- 如果系统调用失败,检查全局变量
errno
以获取具体的错误代码。 - 使用
strerror()
函数将错误代码转换为人类可读的错误信息,并进行适当的错误处理,如打印错误信息、记录日志或采取其他补救措施。
AI: 举一个处理 open()
系统调用错误的例子。
我: 当然,以下是一个处理 open()
系统调用错误的示例代码:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0;
}
在这个例子中,如果 open()
调用失败,fd
将被设置为 -1
,程序会检查 errno
并使用 strerror()
函数将错误代码转换为错误信息,然后打印错误信息并返回1表示程序异常退出。
知识点2:进程控制
AI: 什么是进程?
我: 进程是操作系统进行资源分配和调度的基本单位。每个进程都有自己的地址空间、文件描述符、环境变量等。进程可以包含一个或多个线程,每个线程共享进程的资源。
AI: fork()
系统调用的返回值有什么含义?
我: fork()
系统调用的返回值有三种可能:
- 如果
fork()
成功,它会在父进程中返回子进程的PID(进程标识符),在子进程中返回0。 - 如果
fork()
失败,它会返回-1,并设置全局变量errno
以指示具体的错误原因。
AI: exec()
系统调用的变种有哪些?
我: exec()
系统调用有多个变种,它们的主要区别在于参数的传递方式:
execl()
: 以固定数量的参数调用新程序。execlp()
: 类似于execl()
,但会在环境变量PATH
中查找可执行文件。execle()
: 类似于execl()
,但允许传递环境变量。execv()
: 以数组形式传递参数。execvp()
: 类似于execv()
,但会在环境变量PATH
中查找可执行文件。execvpe()
: 类似于execvp()
,但允许传递环境变量。
AI: wait()
系统调用的参数和返回值是什么?
我: wait()
系统调用的原型如下:
pid_t wait(int *status);
- 参数
status
是一个指向整数的指针,用于接收子进程的退出状态。如果不需要获取退出状态,可以将status
设为NULL
。 - 返回值是子进程的PID。如果没有子进程结束,
wait()
会阻塞父进程。如果wait()
失败,它会返回-1,并设置全局变量errno
以指示具体的错误原因。
AI: 举一个使用 fork()
和 exec()
的示例。
我: 当然,以下是一个使用 fork()
和 exec()
的示例代码:
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);fprintf(stderr, "Failed to execute ls\n");return 1;} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0;
}
在这个例子中,父进程调用 fork()
创建一个子进程。子进程调用 execlp()
执行 /bin/ls
命令,列出当前目录的详细信息。父进程调用 wait()
等待子进程结束,然后打印一条消息表示子进程已经结束。
学习实践过程遇到的问题与解决方式
问题1:fork()
调用后,子进程和父进程同时运行导致输出混乱
描述:在使用 fork()
创建子进程后,子进程和父进程同时运行,导致输出混乱,难以区分哪个输出来自哪个进程。
解决方式:
- 使用
sleep()
临时解决:#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程sleep(1); // 让子进程稍微延迟一下printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; }
- 使用
wait()
确保子进程先结束:#include <stdio.h> #include <unistd.h> #include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程printf("Child process: PID = %d, PPID = %d\n", getpid(), getppid());execlp("/bin/ls", "ls", "-l", NULL);} else {// 父进程wait(NULL); // 等待子进程结束printf("Parent process: PID = %d, Child PID = %d\n", getpid(), pid);printf("Child process finished\n");}return 0; }
问题2:exec()
调用失败,程序无法执行新程序
描述:在调用 exec()
系列函数时,程序无法成功执行新程序,导致程序挂起或报错。
解决方式:
- 检查路径和文件名:
确保提供的路径和文件名是正确的。如果使用execlp()
或execvp()
,确保环境变量PATH
中包含了可执行文件的路径。 - 检查错误信息:
使用perror()
或strerror(errno)
打印详细的错误信息。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程execlp("/bin/ls", "ls", "-l", NULL);perror("Failed to execute ls"); // 打印错误信息return 1;} else {// 父进程wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0; }
问题3:open()
系统调用失败,无法打开文件
描述:在调用 open()
系统调用时,无法打开指定的文件,导致程序出错。
解决方式:
- 检查文件路径和权限:
确保文件路径是正确的,并且当前用户有权限访问该文件。 - 检查错误信息:
使用perror()
或strerror(errno)
打印详细的错误信息。#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h>int main() {int fd = open("nonexistent_file.txt", O_RDONLY);if (fd == -1) {fprintf(stderr, "Error opening file: %s\n", strerror(errno));return 1;}close(fd);return 0; }
问题4:wait()
调用后,父进程无法正确捕获子进程的退出状态
描述:在调用 wait()
系统调用后,父进程无法正确捕获子进程的退出状态,导致程序逻辑出错。
解决方式:
使用 WIFEXITED
和 WEXITSTATUS
宏:
使用 WIFEXITED
检查子进程是否正常退出,使用 WEXITSTATUS
获取子进程的退出状态。
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程execlp("/bin/ls", "ls", "-l", NULL);perror("Failed to execute ls");return 1;} else {// 父进程int status;pid_t child_pid = wait(&status);if (WIFEXITED(status)) {printf("Child process %d exited with status %d\n", child_pid, WEXITSTATUS(status));} else {printf("Child process %d terminated abnormally\n", child_pid);}}return 0;
}
问题5:环境变量传递失败,子进程无法获取正确的环境变量
描述:在使用 exec()
系列函数时,子进程无法获取正确的环境变量,导致程序出错。
解决方式:
检查环境变量的传递方式:
确保在调用 exec()
系列函数时正确传递了环境变量。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {pid_t pid = fork();if (pid < 0) {fprintf(stderr, "Fork failed\n");return 1;} else if (pid == 0) {// 子进程char *new_env[] = {"PATH=/usr/bin:/bin", "MY_VAR=value", NULL};execle("/bin/ls", "ls", "-l", NULL, new_env);perror("Failed to execute ls");return 1;} else {// 父进程wait(NULL); // 等待子进程结束printf("Child process finished\n");}return 0;
}
参考资料
- HeadFirstC嗨翻C语言
- 通义千问
- Linux System Calls
- Process Control in Linux
- Error Handling in C
- 课程 mindmap
- Mermaid Live Editor
相关文章:

第九周预习报告
文章目录 第九周预习报告学习内容AI 对学习内容的总结章节概述内容总结 对知识总结的反思思维导图基于AI的学习知识点1:系统调用知识点2:进程控制 学习实践过程遇到的问题与解决方式问题1:fork() 调用后,子进程和父进程同时运行导…...

【分享】这篇教程助力你成为 JavaScript 糕手!(四)
第四章:运算符与表达式 4.1 算术运算符 加法运算符():用于数字相加,如console.log(5 3);结果为8。 当用于字符串时,它表示字符串拼接。例如console.log(‘Hello’ ‘world’);输出Hello world。如果一个操…...

双亲委派模型的破坏
双亲委派模型的第一次“被破坏”其实发生在双亲委派模型出现之前--即JDK1.2发布之前。由于双亲委派模型是在JDK1.2之后才被引入的,而类加载器和抽象类java.lang.ClassLoader则是JDK1.0时候就已经存在,面对已经存在 的用户自定义类加载器的实现代码,Java设计者引入双亲委派模…...

Android关机流程知多少?
在 Android 中,关机流程涉及系统各个组件的协同工作,确保设备在断电之前能够安全地关闭所有活动并保存数据。以下是 Android 系统中关机流程的详细介绍: 1. 用户触发关机请求 关机流程由用户的操作触发,通常有以下几种方式&#…...

深入理解指针end(总结篇)
如果有不会的智识点,请移动到博主前四篇指针博客! 可以当一个指针智商检阅博客看。 看看你是否掌握了这些知识 1:内存,指针变量 内存单元的编号地址指针; 指针变量和其他变量没有区别,指针变量是来存放…...

C# 程序暂停的两种方式
C# 程序暂停的两种方式:EventWaitHandle 与 volatile bool pause 在C#中,线程控制是多线程编程的重要组成部分,其中实现暂停的需求经常出现。本文将详细探讨使用EventWaitHandle和设置volatilebool来实现线程暂停的不同方式,它们…...

【LeetCode】【算法】160.相交链表
Leetcode 160. 相交链表 题目描述 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 思路 AB,一个指针,访问完A访问B;另一个指针&#…...

光伏破局 引领能源革命
为进一步推进商业信用体系建设,促进企业诚实守信经营,面向企业普及诚信与品牌建设的意义,指导企业加强诚信品牌建设,提升其整体竞争力,“崛起的民族品牌”专题系列节目以诚信为内涵,在全国范围内遴选出有行…...

Jenkins声明式Pipeline流水线语法示例
系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline?1.2、为什么使用pi…...

互联网技术净土?原生鸿蒙开启全新技术征程
鸿蒙生态与开发者的崭新机会 HarmonyOS NEXT承载着华为对未来操作系统的深刻理解,如今已发展为坚实的数字底座。它不仅在技术层面取得了全面突破,还在中国操作系统市场中站稳了脚跟。 当前,HarmonyOS NEXT的代码行数已超过1.1亿,…...

关于Django 模型字段 `choices`自定义数据类型的枚举——补充
文章目录 1. 处理 datetime 类型的 choices2. 处理 time 类型的 choices3. 处理 Decimal 类型的 choices4. 处理 UUID 类型的 choices5. 处理 float 类型的 choices 在 Choices 类的基础上扩展,可以将 choices 与特定数据类型(如 date 或 datetime&a…...

CAP理论的延申--BASE理论
上一篇文章我简单介绍了一下什么是CAP理论,本篇文章讲解一下随着技术的演变,CAP理论是如何发展为BASE理论的。 CAP理论回顾 首先我们回顾一下CAP理论,CAP理论指得是分布式系统发生网络等故障时,不同节点之间无法同步数据…...

【傻呱呱】phpMyAdmin怎样给特定用户授权特定数据库权限?
前期准备 phpMyAdmin数据库(MySQL) END...

『VUE』21. 组件注册(详细图文注释)
目录 组件注册局部注册全局注册全局注册示例总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 组件注册 组件注册有两种方式:全局注册和局部注册。全局注册只需要注册依次,其他组件可以直接调用无需再次像局部注册一…...

如何产看SQL 查询的执行时间
要查看 SQL 查询的执行时间,尤其是毫秒级别,可以使用以下几种方法: 方法 1:使用 SET STATISTICS TIME 查看执行时间 SET STATISTICS TIME 会显示执行时间的详细信息,包括 CPU 时间和总耗时。启用后,SQL S…...

计算机网络——路由器构成
算路由表是分布式去算——你算你的,我算我的 输出队列非先来先传 调度发生在哪里 缓存队列一般是应对——来数据方向的速度过快问题...

架构师之路-学渣到学霸历程-48
实现域名跳转的实验 今天继续还是分享域名跳转的实验;继续整,看看效果 意思就是你本来访问www.liangjiawei.net的网站然后跳转到blog.liangjiawei.net的网站 1、基础的环境部署 安装好nginx(这里最好的就是干净的环境)创建两个…...

HappyChart——一款简单好用的专业绘图软件
HappyChart是一款新出的专业绘图软件,灵感来自于类PS软件,它是以图层的方式进行绘图。相比与Excel图表或其他专业绘图软件,HappyChart界面简洁明了,操作简单,没有复杂的选项,它只调整绘图相关参数即可实时展…...

【Linux】进程信号全攻略(二)
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 再谈信号的捕捉 🦋 关于信号捕捉的细节部分(sigaction函数) 二:🔥 穿插话题 - 操作系统是怎么运…...

redis用法(二)
文章目录 02-redis数据类型篇生产环境下的redis实况图 1.全局命令redis数据存储格式set设置k-v查看当前redis的key的数量危险命令,新手请在于超老师陪同下执行为什么危险?如何正确搜索redis的key 查看库下有多少个key查询redis库信息切换redis库查看key是…...

Python-利用os,tkinter库编写一个伪恶意程序文件(Pro版)
前言:上一期我们简单学习了如何编写一个多次弹窗警告用户的exe伪恶意文件。我们知道了把Python初始文件编译为exe文件后,程序在没有Python环境的情况下也能正常运行。我们上次编写的程序仅仅只是伪造系统正在执行关机命令前的倒计时的假象,实…...

Oracle视频基础1.4.4练习
1.4.4 [dbs] 删干净上次创建的bbk ll rm -f *dbf ll rm -f spfilebbk.ora clear ll创建bbk的pfile,准备对应的目录 ll strings spfilewilson.ora | more strings spfilewilson.ora > initbbk.ora :%s/wilson/bbk :%s/*\.//g :wq ll vi initbbk.ora####### 创…...

GOF的C++软件设计模式的分类和模式名称
“GOF” 指的是 “Gang of Four”,即“四人帮”,他们是指 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides。这四位作者在其著作《Design Patterns: Elements of Reusable Object-Oriented Software》中定义了23种设计模式,这些…...

有向图的完全可达性(有向图搜索全路径的问题) C#DFs
在考察输入输出方面我觉得是道难题了 第一次遇见邻接表的数据结构该怎么声明 卡码网105 在力扣没找见完全相同的题 感觉需要多练习多复习这种类型的题 105. 有向图的完全可达性 题目描述 给定一个有向图,包含 N 个节点,节点编号分别为 1&…...

前端开发实现自定义勾选/自定义样式,可复选,可取消勾选
基于后端返回数组实现多选、复选 以下代码基于vue2,如果有需要React/Vue3或者其他框架代码的,可以通过国内直连GPT4o进行代码转换,转换正确率99% 前端代码如下(直接拷贝到你的vue代码即可): <!-- CustomCheckboxList.vue --&g…...

鸿蒙-promptAction.showToast基于PC屏幕底部提示
PC端app缩小,右击出菜单后,点菜单项 菜单关闭,并弹promptAction.showToast提示,但提示是基于PC底部弹提示的,需要的是基于app底部弹提示 原因是UIContext是右击菜单的UIContext,需要拿到菜单下面UI的UICont…...

Vert.x,应用监控 - 全链路跟踪,基于Zipkin
关于Zipkin Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),能够收集服务间调用的时序数据,提供调用链路的追踪。Zipkin每一个调用链路通过一个trace id来串联起来,通过trace id,就能够直接定位到这次调…...

Rust常用数据结构教程 序列
文章目录 一、Vec1.Vec与堆栈2.什么时候需要Vec3.get()方法4.与枚举的结合 二、VecDeque1.什么情况适合VecDeque2.VecDeque的方法 三、LinkedList1.什么时候用LinkedList 参考 一、Vec 可变数组(vector)数组存储在heap上,在运行时(runtime)可以增加或减少数组 长度 有人把Ve…...

智慧城市路面垃圾识别系统产品介绍方案
方案介绍 智慧城市中的路面垃圾识别算法通常基于深度学习框架,这些算法因其在速度和精度上的优势而被广泛采用。这些模型能够通过训练识别多种类型的垃圾,包括塑料袋、纸屑、玻璃瓶等。系统通过训练深度学习模型,使其能够识别并定位多种类型…...

网络安全:构建坚固的数字堡垒
网络安全:构建坚固的数字堡垒 在当今数字化时代,网络安全已经成为企业和个人不可忽视的重要议题。随着互联网的普及和信息技术的快速发展,网络攻击、数据泄露和隐私侵犯等问题日益严重,给企业和个人带来了巨大的风险和损失。本文…...