当前位置: 首页 > news >正文

第九周预习报告

文章目录

  • 第九周预习报告
    • 学习内容
    • 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: 如何处理系统调用的错误?

: 处理系统调用的错误通常涉及以下几个步骤:

  1. 检查系统调用的返回值。大多数系统调用在成功时返回一个有意义的值,而在失败时返回一个错误码(通常是负数)。
  2. 如果系统调用失败,检查全局变量 errno 以获取具体的错误代码。
  3. 使用 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() 创建子进程后,子进程和父进程同时运行,导致输出混乱,难以区分哪个输出来自哪个进程。
解决方式

  1. 使用 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;
    }
    
  2. 使用 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() 系列函数时,程序无法成功执行新程序,导致程序挂起或报错。
解决方式

  1. 检查路径和文件名
    确保提供的路径和文件名是正确的。如果使用 execlp()execvp(),确保环境变量 PATH 中包含了可执行文件的路径。
  2. 检查错误信息
    使用 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() 系统调用时,无法打开指定的文件,导致程序出错。
解决方式

  1. 检查文件路径和权限
    确保文件路径是正确的,并且当前用户有权限访问该文件。
  2. 检查错误信息
    使用 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() 系统调用后,父进程无法正确捕获子进程的退出状态,导致程序逻辑出错。
解决方式
使用 WIFEXITEDWEXITSTATUS
使用 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&#xff1a;系统调用知识点2&#xff1a;进程控制 学习实践过程遇到的问题与解决方式问题1&#xff1a;fork() 调用后&#xff0c;子进程和父进程同时运行导…...

【分享】这篇教程助力你成为 JavaScript 糕手!(四)

第四章&#xff1a;运算符与表达式 4.1 算术运算符 加法运算符&#xff08;&#xff09;&#xff1a;用于数字相加&#xff0c;如console.log(5 3);结果为8。 当用于字符串时&#xff0c;它表示字符串拼接。例如console.log(‘Hello’ ‘world’);输出Hello world。如果一个操…...

双亲委派模型的破坏

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

Android关机流程知多少?

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

深入理解指针end(总结篇)

如果有不会的智识点&#xff0c;请移动到博主前四篇指针博客&#xff01; 可以当一个指针智商检阅博客看。 看看你是否掌握了这些知识 1&#xff1a;内存&#xff0c;指针变量 内存单元的编号地址指针&#xff1b; 指针变量和其他变量没有区别&#xff0c;指针变量是来存放…...

C# 程序暂停的两种方式

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

【LeetCode】【算法】160.相交链表

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

光伏破局 引领能源革命

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

Jenkins声明式Pipeline流水线语法示例

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

互联网技术净土?原生鸿蒙开启全新技术征程

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

关于Django 模型字段 `choices`自定义数据类型的枚举——补充

文章目录 1. 处理 datetime 类型的 choices2. 处理 time 类型的 choices3. 处理 Decimal 类型的 choices4. 处理 UUID 类型的 choices5. 处理 float 类型的 choices 在 Choices 类的基础上扩展&#xff0c;可以将 choices 与特定数据类型&#xff08;如 date 或 datetime&a…...

CAP理论的延申--BASE理论

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

【傻呱呱】phpMyAdmin怎样给特定用户授权特定数据库权限?

前期准备 phpMyAdmin数据库&#xff08;MySQL&#xff09; END...

『VUE』21. 组件注册(详细图文注释)

目录 组件注册局部注册全局注册全局注册示例总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 组件注册 组件注册有两种方式&#xff1a;全局注册和局部注册。全局注册只需要注册依次,其他组件可以直接调用无需再次像局部注册一…...

如何产看SQL 查询的执行时间

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

计算机网络——路由器构成

算路由表是分布式去算——你算你的&#xff0c;我算我的 输出队列非先来先传 调度发生在哪里 缓存队列一般是应对——来数据方向的速度过快问题...

架构师之路-学渣到学霸历程-48

实现域名跳转的实验 今天继续还是分享域名跳转的实验&#xff1b;继续整&#xff0c;看看效果 意思就是你本来访问www.liangjiawei.net的网站然后跳转到blog.liangjiawei.net的网站 1、基础的环境部署 安装好nginx&#xff08;这里最好的就是干净的环境&#xff09;创建两个…...

HappyChart——一款简单好用的专业绘图软件

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

【Linux】进程信号全攻略(二)

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 再谈信号的捕捉 &#x1f98b; 关于信号捕捉的细节部分&#xff08;sigaction函数&#xff09; 二&#xff1a;&#x1f525; 穿插话题 - 操作系统是怎么运…...

redis用法(二)

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

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...