01 - QEMU 初始化概览 - Init()
目录
1.初始化 - qemu_init()
1.1.基本设备
1.2.日志
1.3.模块信息
1.4.子系统
1.5.选项解析 - 阶段一
1.6.选项解析 - 阶段二
1.7.选项配置
1.8.Trace
1.9.主线程
1.10.CPU 时钟
1.11.其他设置
1.12.创建虚拟机
1.13.启动虚拟机
2.主线程 - qemu_main()
2.1.处理关机/重启等请求 - main_loop_should_exit()
2.2.检查外部事件 - main_loop_wait()
main() 函数位于 system 目录,主要做两件事:初始化、执行 main 函数:
// system/main.c
int qemu_default_main(void)
{...status = qemu_main_loop();
-------------------------------------------// system/main.c
int (*qemu_main)(void) = qemu_default_main;
-------------------------------------------// system/main.c
int main(int argc, char **argv)
{qemu_init(argc, argv); // 初始化return qemu_main(); // 执行 qemu_main_loop()
1.初始化 - qemu_init()
qemu_init() 完成虚拟机运行环境的准备工作、解析用户指令、配置并最终启动虚拟机
1.1.基本设备
-
解析命令行,将 -device 等参数保存至 vm_config_groups 和 drive_config_groups:
// system/vl.c
void qemu_init(int argc, char **argv)
{...// 解析命令行参数qemu_add_opts(&qemu_drive_opts);qemu_add_drive_opts(&qemu_legacy_drive_opts);
-
调用 QEMU 初始化函数 init(),对 CPU、VNC、Trace 等基本环境执行初始化:
// system/vl.c
void qemu_init(int argc, char **argv)
{...// QEMU 基本初始化,如 CPU、VNC、trace 等module_call_init(MODULE_INIT_OPTS);
-------------------------------------------// util/module.c
void module_call_init(module_init_type type)
{...ModuleEntry *e;...QTAILQ_FOREACH(e, l, node) {e->init();
module_call_init() 调用 QTAILQ_FOREACH() 查找 VNC、Trace 等模块,并调用其 init() 方法,例如:
1.2.日志
QEMU 的日志输出调用 GLib 接口,主要设置 Log 打印的前缀等基本信息
对于 Linux 系统,调用 readlink() 读取当前程序执行的绝对路径(对于其他系统调用其对应的接口)
// system/vl.c
void qemu_init(int argc, char **argv)
{...error_init(argv[0]); // 设置日志定向输出qemu_init_exec_dir(argv[0]); // 获取当前程序位置
---------------------------------------------------------------------// util/error-report.c
void error_init(const char *argv0)
{...g_set_prgname(p ? p + 1 : argv0); // 设置程序名称...g_log_set_default_handler(qemu_log_func, NULL); // 设置日志打印函数
---------------------------------------------------------------------// util/cutils.c
void qemu_init_exec_dir(const char *argv0)
{...len = readlink("/proc/self/exe", buf, sizeof(buf) - 1); // 读取当前程序的路径
QEMU 的日志打印通过调用 Glib 的 G_GNUC_PRINTF 接口实现:
// include/qemu/error-report.h
void error_report(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
void warn_report(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
void info_report(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
---------------------------------------------------------------------// util/error-report.c
static void qemu_log_func(const gchar *log_domain, GLogLevelFlags log_level,const gchar *message, gpointer user_data)
{switch (log_level & G_LOG_LEVEL_MASK) {...case G_LOG_LEVEL_MESSAGE:info_report("%s%s%s", log_domain ?: "", log_domain ? ": " : "", message);break;
1.3.模块信息
QEMU 模块信息如下所示:
// include/qemu/module.h
struct QemuModinfo {const char *name;const char *arch;const char **objs;const char **deps;const char **opts;
};
extern const QemuModinfo qemu_modinfo[];
绑定相关信息:
// system/vl.c
void qemu_init(int argc, char **argv)
{...qemu_init_arch_modules();
---------------------------------------------------------------------// system/arch_init.c
void qemu_init_arch_modules(void)
{
#ifdef CONFIG_MODULESmodule_init_info(qemu_modinfo);|--> module_info = info; // 绑定模块信息module_allow_arch(TARGET_NAME);|--> module_arch = arch; // 设置架构名称如 aarch64、arm 等
1.4.子系统
POSIX 和 WIN32 分别调用对应的接口,创建 Trace、QOM 等基本模块,初始化 CPU 线程相关 pthread 变量:
// system/vl.c
void qemu_init(int argc, char **argv)
{...qemu_init_subsystems();
---------------------------------------------------------------------// system/runstate.c
void qemu_init_subsystems(void)
{...
---------------------------------------------------------------------// 设置输出缓冲,输出打印按行(_IOLBF)存入缓冲区os_set_line_buffering();|--> setvbuf(stdout, NULL, _IOLBF, 0);// Trace 初始化module_call_init(MODULE_INIT_TRACE);
------------------------------------------------------------------------------------------------------------------------------------------// CPU 对于操作系统就是一个可以执行线程的单元// 对 CPU 的初始化也就是对线程执行初始化,包括锁、信号等qemu_init_cpu_list();|--> qemu_mutex_init(&qemu_cpu_list_lock);|--> qemu_cond_init(&exclusive_cond);|--> qemu_cond_init(&exclusive_resume);|--> qemu_cond_init(&qemu_work_cond);qemu_init_cpu_loop();|--> qemu_init_sigbus();|--> qemu_cond_init(&qemu_cpu_cond);|--> qemu_cond_init(&qemu_pause_cond);|--> qemu_mutex_init(&bql);|--> qemu_thread_get_self(&io_thread);bql_lock(); // Lock the Big QEMU Lock
------------------------------------------------------------------------------------------------------------------------------------------// 设置程序退出时执行的回调函数atexit(qemu_run_exit_notifiers);|--> notifier_list_notify(&exit_notifiers, NULL);
------------------------------------------------------------------------------------------------------------------------------------------// QOM 初始化module_call_init(MODULE_INIT_QOM);// 可迁移设备初始化module_call_init(MODULE_INIT_MIGRATION);
------------------------------------------------------------------------------------------------------------------------------------------// 初始化虚拟机的运行状态:RUN_STATE_DEBUG、RUN_STATE_PAUSED...runstate_init();
------------------------------------------------------------------------------------------------------------------------------------------// 设置回调函数precopy_infrastructure_init();postcopy_infrastructure_init();
------------------------------------------------------------------------------------------------------------------------------------------// 初始化监视器(串口)monitor_init_globals();
---------------------------------------------------------------------...
---------------------------------------------------------------------// 设置系统如何处理SIGQUIT、SIGKILL等信号os_setup_early_signal_handling();
------------------------------------------------------------------------------------------------------------------------------------------// 初始化一些块驱动(block driver)如硬盘、内存等bdrv_init_with_whitelist();
------------------------------------------------------------------------------------------------------------------------------------------// 该函数只对 Win32 的 socket 调用对应接口进行初始化socket_init();
1.5.选项解析 - 阶段一
对传入参数进行检查,如果没有检测到用户传入的指定参数则使用默认设置:
// system/vl.c
void qemu_init(int argc, char **argv)
{.../* first pass of option parsing */optind = 1;while (optind < argc) {
---------------------------------------------------------------------// 传入参数前不带 '-' 的会被认为是镜像文件if (argv[optind][0] != '-') {/* disk image */optind++;
---------------------------------------------------------------------} else {const QEMUOption *popt;// 解析cmdlinepopt = lookup_opt(argc, argv, &optarg, &optind);switch (popt->index) {case QEMU_OPTION_nouserconfig:userconfig = false;break;}}}
---------------------------------------------------------------------// 用于保存传入的启动参数machine_opts_dict = qdict_new();
---------------------------------------------------------------------// 如果没有检测到用户传入的参数,则使用默认的配置if (userconfig) { qemu_read_default_config_file(&error_fatal);
QEMU 定义了 QEMUOption 结构体描述运行时传入的选项参数:
// system/vl.c
typedef struct QEMUOption {const char *name; // 选项名,如 -device, name 的值就是 deviceint flags; // 标志位,表示选项是否带参数,可以是 0,或者 HAS_ARG(值为0x0001)int index; // 枚举类型的值,如 -device,该值就是 QEMU_OPTION_deviceuint32_t arch_mask; // 该选项支持架构的掩码
} QEMUOption;
1.6.选项解析 - 阶段二
详细解析各个参数,设置对应的值或预处理,并将这些参数保存在 machine_opts_dict 中:
// system/vl.c
void qemu_init(int argc, char **argv)
{.../* second pass of option parsing */optind = 1;for(;;) {...if (argv[optind][0] != '-') {loc_set_cmdline(argv, optind, 1);drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS);} else {const QEMUOption *popt;popt = lookup_opt(argc, argv, &optarg, &optind);...switch(popt->index) {...case QEMU_OPTION_nographic: // -nographic 参数qdict_put_str(machine_opts_dict, "graphics", "off");nographic = true;dpy.type = DISPLAY_TYPE_NONE;break;...case QEMU_OPTION_kernel: // -kernel 参数qdict_put_str(machine_opts_dict, "kernel", optarg);break;
1.7.选项配置
验证镜像相关参数的正确性,配置 CPU 个数、内存、线程、守护进程等:
// system/vl.c
void qemu_init(int argc, char **argv)
{...
---------------------------------------------------------------------// 验证镜像相关参数正确性qemu_validate_options(machine_opts_dict);
------------------------------------------------------------------------------------------------------------------------------------------// 配置 CPU 数量、内存、预分配线程等qemu_process_sugar_options();
---------------------------------------------------------------------...
---------------------------------------------------------------------// 配置守护进程qemu_maybe_daemonize(pid_file);
1.8.Trace
创建 Trace 线程如 Full Trace、Simple Trace 等,设置用于记录 Trace 的文件:
// system/vl.c
void qemu_init(int argc, char **argv)
{...
---------------------------------------------------------------------// 创建 Trace 线程if (!trace_init_backends()) {|--> st_init() // 初始化 Simple Trace 线程|--> thread = trace_thread_create(writeout_thread);|--> atexit(st_flush_trace_buffer);|--> ftrace_init() // 初始化 FTrace|--> tracefs_found = find_mount(mount_point, "tracefs");|--> trace_fd = open(path, O_WRONLY);
---------------------------------------------------------------------...
---------------------------------------------------------------------trace_init_file(); // 设置 Trace 文件|--> st_set_trace_file(trace_opts_file);
1.9.主线程
QEMU 主线程使用 GLib 的 Main Loop 实现:
// system/vl.c
void qemu_init(int argc, char **argv)
{...// 创建 QEMU 主线程qemu_init_main_loop(&error_fatal);
创建 Main Loop 所需的上下文、信号量、文件描述符等:
// util/main-loop.c
int qemu_init_main_loop(Error **errp)
{...
---------------------------------------------------------------------// 初始化时钟,注册回调函数init_clocks(qemu_timer_notify_cb);|--> qemu_clock_init(type, notify_cb);|--> main_loop_tlg.tl[type] = timerlist_new(type, notify_cb, NULL);|--> timer_list->clock = clock;|--> timer_list->notify_cb = cb; // qemu_timer_notify_cb 即为 timer_list 的回调函数
------------------------------------------------------------------------------------------------------------------------------------------// 初始化信号量ret = qemu_signal_init(errp);|--> sigemptyset()、sigaddset() // 信号函数集|--> sigfd = qemu_signalfd(&set);|--> g_unix_set_fd_nonblocking(sigfd, true, NULL); // 将 fd 设置为非阻塞|--> qemu_set_fd_handler(sigfd, sigfd_handler, NULL, (void *)(intptr_t)sigfd);|--> iohandler_init(); // 如果没有 AIO 上下文,则创建一个|--> iohandler_ctx = aio_context_new(&error_abort);|--> aio_set_fd_handler(); // 使用 AIO 线程(异步非阻塞)处理 fd
------------------------------------------------------------------------------------------------------------------------------------------// 创建 AIO Contextqemu_aio_context = aio_context_new(errp);|--> ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));// 获取并设置 AIO Contextqemu_set_current_aio_context(qemu_aio_context);|--> assert(!get_my_aiocontext()); // 如果已存在 AIO Context 则直接获取|--> set_my_aiocontext(ctx); // 否则新建一个
------------------------------------------------------------------------------------------------------------------------------------------// 挂载 notify callbackqemu_notify_bh = qemu_bh_new(notify_event_cb, NULL);|--> notify_event_cb() // 回调函数:使内核退出 POLL 状态(停止监听 fd)|--> qemu_bh_new_full()|--> aio_bh_new_full() // 挂载回调函数
------------------------------------------------------------------------------------------------------------------------------------------// 新建用于监听的 fdgpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
------------------------------------------------------------------------------------------------------------------------------------------// 创建事件源(自定义事件源):aio-contextsrc = aio_get_g_source(qemu_aio_context); // 获取 Gsource 事件源|--> aio_context_use_g_source(ctx);|--> g_source_ref(&ctx->source);|--> return &ctx->source;// 设置事件源名称g_source_set_name(src, "aio-context");// 添加事件源g_source_attach(src, NULL);// 释放引用g_source_unref(src);
---------------------------------------------------------------------// 创建事件源(自定义事件源):io-handlersrc = iohandler_get_g_source();g_source_set_name(src, "io-handler");g_source_attach(src, NULL); // 绑定 GSource
1.10.CPU 时钟
初始化 CPU 定时器,该定时器周期性 Poll FD,检查是否存在外设事件,如果有则通知 CPU 进行处理(回调):
// system/vl.c
void qemu_init(int argc, char **argv)
{...// 初始化 CPU Timercpu_timers_init();
---------------------------------------------------------------------// system/cpu-timers.c
void cpu_timers_init(void)
{seqlock_init(&timers_state.vm_clock_seqlock);|--> sl->sequence = 0;qemu_spin_init(&timers_state.vm_clock_lock);|--> qatomic_set(&spin->value, 0);vmstate_register(NULL, 0, &vmstate_timers, &timers_state);cpu_throttle_init();
1.11.其他设置
注册用户定义的全局 Property、应答模式选择、配置 RTC、设置虚拟机内存等相关属性:
// system/vl.c
void qemu_init(int argc, char **argv)
{...
---------------------------------------------------------------------// Property注册user_register_global_props();|--> qemu_opts_foreach(qemu_find_opts("global"), global_init_func, NULL, NULL);
------------------------------------------------------------------------------------------------------------------------------------------// 应答模式选择replay_configure(icount_opts);
------------------------------------------------------------------------------------------------------------------------------------------// RTC(Real Time Clock)configure_rtc(qemu_find_opts_singleton("rtc"));
---------------------------------------------------------------------/* Transfer QemuOpts options into machine options */parse_memory_options(); // 设置虚拟机内存相关属性
1.12.创建虚拟机
根据 cmdline 选择的架构及平台创建对应虚拟机,同时创建虚拟机板载相关设备如 CPU、内存、中断控制器等
同时,为虚拟机配置加速器(TCG or KVM),相关设备创建完成后调用其初始化及实例化相关方法
// system/vl.c
void qemu_init(int argc, char **argv)
{...
---------------------------------------------------------------------// 创建虚拟机:New machine_classqemu_create_machine(machine_opts_dict);
---------------------------------------------------------------------...
---------------------------------------------------------------------// 设备初始化 qemu_disable_default_devices();
------------------------------------------------------------------------------------------------------------------------------------------// 显示输出(VGA、VNC等)qemu_setup_display();
------------------------------------------------------------------------------------------------------------------------------------------// 创建一些基本设备,如 I/O 等qemu_create_default_devices();
------------------------------------------------------------------------------------------------------------------------------------------// 创建窗口用于图像和声音的输出qemu_create_early_backends();
------------------------------------------------------------------------------------------------------------------------------------------// 创建虚拟机前的一些准备工作:KVM、Memory 等设置qemu_apply_legacy_machine_options(machine_opts_dict);qemu_apply_machine_options(machine_opts_dict);qobject_unref(machine_opts_dict);
---------------------------------------------------------------------...
---------------------------------------------------------------------// 硬件加速:TCG、KVMconfigure_accelerators(argv[0]);
---------------------------------------------------------------------...
---------------------------------------------------------------------// 如果使用了高版本的语法,而且低版本可能不支持时,需要在编译或运行时做一些转换machine_class = MACHINE_GET_CLASS(current_machine);if (!qtest_enabled() && machine_class->deprecation_reason) {...
---------------------------------------------------------------------// 多核心管理初始化:创建并初始化migration_object_init();|--> current_migration = MIGRATION_OBJ(object_new(TYPE_MIGRATION));|--> init()
---------------------------------------------------------------------/* parse features once if machine provides default cpu_type */current_machine->cpu_type = machine_class_default_cpu_type(machine_class);if (cpu_option) {current_machine->cpu_type = parse_cpu_option(cpu_option);...
---------------------------------------------------------------------// 设置内存qemu_resolve_machine_memdev();
---------------------------------------------------------------------.---------------------------------------------------------------------// 非一致性内存访问:NUMAparse_numa_opts(current_machine);
------------------------------------------------------------------------------------------------------------------------------------------// 是否需要打印虚拟机目前的相关信息if (vmstate_dump_file) {/* dump and exit */module_load_qom_all();dump_vmstate_json_to_file(vmstate_dump_file);exit(0);}if (!preconfig_requested) {// 调用初始化及实例化相关方法qmp_x_exit_preconfig(&error_fatal);|--> qemu_init_board()|--> machine_run_board_init()
1.13.启动虚拟机
设置显示输出位置及配置 VNC、启动加速器、程序后台运行,允许字符设备输入输出:
// system/vl.c
void qemu_init(int argc, char **argv)
{...
---------------------------------------------------------------------// 初始化显示,在这里启动了VNCqemu_init_displays();|--> qemu_display_init(ds, &dpy);|--> qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, &error_fatal);
------------------------------------------------------------------------------------------------------------------------------------------// 硬件加速器accel_setup_post(current_machine);
------------------------------------------------------------------------------------------------------------------------------------------// 启动守护线程设置后台运行os_setup_post();
------------------------------------------------------------------------------------------------------------------------------------------// 外设(各类字符设备,如鼠标、串口等)resume_mux_open();
2.主线程 - qemu_main()
设备初始化完成后运行 qemu_main() 函数,main() 循环等待事件,若监听到新事件则调用 notifier 进行通知:
// system/main.c
int qemu_default_main(void)
{...status = qemu_main_loop();
---------------------------------------------------------------------// system/main.c
int (*qemu_main)(void) = qemu_default_main;
---------------------------------------------------------------------// system/main.c
int main(int argc, char **argv)
{...return qemu_main();
---------------------------------------------------------------------// system/runstate.c
int qemu_main_loop(void)
{...while (!main_loop_should_exit(&status)) {main_loop_wait(false);
2.1.处理关机/重启等请求 - main_loop_should_exit()
检查是否存在重启、关机、唤醒等请求并执行相应的处理流程:
// system/runstate.c
static bool main_loop_should_exit(int *status)
{...
---------------------------------------------------------------------// 调试请求if (qemu_debug_requested()) {vm_stop(RUN_STATE_DEBUG);}
------------------------------------------------------------------------------------------------------------------------------------------// 虚拟机挂起请求if (qemu_suspend_requested()) {qemu_system_suspend();}
------------------------------------------------------------------------------------------------------------------------------------------// 关机请求request = qemu_shutdown_requested(); if (request) {qemu_kill_report();qemu_system_shutdown(request);if (shutdown_action == SHUTDOWN_ACTION_PAUSE) {vm_stop(RUN_STATE_SHUTDOWN);...}
------------------------------------------------------------------------------------------------------------------------------------------// 重启请求request = qemu_reset_requested(); if (request) {pause_all_vcpus();qemu_system_reset(request);resume_all_vcpus();...}
------------------------------------------------------------------------------------------------------------------------------------------// 唤醒请求if (qemu_wakeup_requested()) { pause_all_vcpus();qemu_system_wakeup();notifier_list_notify(&wakeup_notifiers, &wakeup_reason);wakeup_reason = QEMU_WAKEUP_REASON_NONE;resume_all_vcpus();qapi_event_send_wakeup();}
------------------------------------------------------------------------------------------------------------------------------------------// 关机请求if (qemu_powerdown_requested()) {qemu_system_powerdown();}
------------------------------------------------------------------------------------------------------------------------------------------// 虚拟机停止运行请求if (qemu_vmstop_requested(&r)) {vm_stop(r);
2.2.检查外部事件 - main_loop_wait()
Poll 轮询是否有事件发生(例如 VNC 连接等)并调用 main_loop_poll_notifiers() 回调函数进行处理:
// util/main-loop.c
void main_loop_wait(int nonblocking)
{MainLoopPoll mlpoll = {.state = MAIN_LOOP_POLL_FILL,.timeout = UINT32_MAX,.pollfds = gpollfds,};...
---------------------------------------------------------------------// 如果是非阻塞模式,超时时间为0if (nonblocking) {mlpoll.timeout = 0;}
------------------------------------------------------------------------------------------------------------------------------------------/* poll any events */g_array_set_size(gpollfds, 0); /* reset for new iteration *//* XXX: separate device handlers from system ones */notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
---------------------------------------------------------------------...
---------------------------------------------------------------------// 计算最小超时时间timeout_ns = qemu_soonest_timeout(timeout_ns,timerlistgroup_deadline_ns(&main_loop_tlg));// 等待超时,随后调用notifierret = os_host_main_loop_wait(timeout_ns);mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);...qemu_clock_run_all_timers();
相关文章:
01 - QEMU 初始化概览 - Init()
目录 1.初始化 - qemu_init() 1.1.基本设备 1.2.日志 1.3.模块信息 1.4.子系统 1.5.选项解析 - 阶段一 1.6.选项解析 - 阶段二 1.7.选项配置 1.8.Trace 1.9.主线程 1.10.CPU 时钟 1.11.其他设置 1.12.创建虚拟机 1.13.启动虚拟机 2.主线程 - qemu_main() 2.1.处…...
Vue3 使用ref
<button click"changeMsg">change</button> <div>{{ message }}</div>//接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。 const message ref(hello world) const mum 1 co…...
React中 点击事件写法 的注意(this、箭头函数)
目录 1、错误写法:onClick{this.acceptAlls()} 2、正确写法:onClick{this.acceptAlls}(不带括号) 总结 方案1:构造函数绑定 方案2:箭头函数包装方法(更简洁) 方案3&am…...
DeepSeek AI大模型:中国智能时代的“争气机“-AI生成
DeepSeek AI大模型:中国智能时代的"争气机" 当全球科技巨头在万亿参数竞赛中你追我赶时,一家中国公司悄然改写了游戏规则。DeepSeek AI最新发布的"探月"大模型不仅以中英双语能力打破技术壁垒,更用"动态脑区"设…...
Java老鼠迷宫(递归)---案例来自韩顺平老师讲Java
题目: 粉色圈圈是启动,红色方框是阻挡,蓝色五角星是出口,走到出口,老鼠winner 代码: public class test6 {public static void main(String[] args){//创建二维数组int[][] map new int[8][7];// 最外围都…...
Python大数据视频教程
概述 最新整理的Python大数据视频教程已出,需要学习的小伙伴抓紧了。 课程亮点: ❶ 编程基石:从Python基础到高阶函数式编程,用代码驯服数据 ❷ 数据魔法:SQL进阶ETL实战,Pandas玩转百万级数据分析 ❸ 分…...
Java工厂模式解析:灵活对象创建的实践指南
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 一、模式定义与分类 工厂模式(Factory Pattern)是创建型设计模式的核心成员之一,主要解决对象创建过程中的灵活性问题。根…...
PDF转换格式失败?原因及解决方法全解析
在日常工作中,我们经常会遇到将PDF转换为Word、Excel、PPT等格式的需求。有时候以为一键转换就能搞掂,没想到却转换失败。到底问题出在哪?别急,我们可以看看是否以下几个问题引起的,找到解决问题的关键! 原…...
《轨道力学讲义》——第五讲:摄动理论基础
第五讲:摄动理论基础 引言 在实际的航天任务中,我们很少能够使用理想的二体问题来精确描述航天器的运动。地球的非球形性、大气阻力、太阳辐射压以及第三天体引力等各种因素都会对航天器轨道产生偏离理想轨道的影响。这些额外的力被称为"摄动力&q…...
【NLP】23.小结:选择60题
Question 1: What does the fixed lookup table in traditional NLP represent? A. A table of one‐hot vectors B. A table of pre‐trained dense word embeddings C. A dictionary of word definitions D. A table of n-gram counts Answer (中文): 答案选 B。传统NLP中“…...
C++核心机制-this 指针传递与内存布局分析
示例代码 #include<iostream> using namespace std;class A { public:int a;A() {printf("A:A()的this指针:%p!\n", this);}void funcA() {printf("A:funcA()的this指针:%p!\n", this);} };class B { public:int b;B() {prin…...
python asyncio 的基本使用
1、引言 asyncio 是 Python 标准库中的一个库,提供了对异步 I/O 、事件循环、协程和任务等异步编程模型的支持。 asyncio 文档 2、进程、线程、协程 线程 线程是操作系统调度的基本单位,同一个进程中的多个线程共享相同的内存空间。线程之间的切换由操…...
大模型中提到的分词器是什么
分词器在大模型中的核心解析 1. 分词器的定义与基本作用 分词器(Tokenizer)是自然语言处理(NLP)中的核心组件,负责将原始文本拆分为模型可处理的离散单元(称为Token)。其核心功能包括: 文本离散化:将连续字符序列转化为数字序列,作为模型的输入。语义单元提取:通过…...
Android中使用BuildConfig.DEBUG无法找到的解决方法
BuildConfig是Android构建工具自动生成的一个类,通常位于应用的包名下,包含一些构建相关的常量,比如DEBUG标志、应用ID、版本信息等。 遇到的问题可能有几种情况。首先,可能项目没有正确构建,导致BuildConfig没有被生…...
Python(14)Python内置函数完全指南:从基础使用到高阶技巧
目录 背景介绍一、内置函数全景分类1. 数据类型转换(15个)2. 数学运算(12个)3. 迭代处理(9个)4. 对象操作(11个)5. 输入输出(4个) 二、高阶函数应用场景1. en…...
echo命令,tail命令,反引号,重定向符
echo命令: 作用:在命令行中输出指定的内容,相当于print语句 语法:echo 指定的内容(当内容包含空格和特殊字符的时候,语句很复杂的时候,最好用双引号括起来) tail命令:…...
集成学习介绍
集成学习(Ensemble Learning)是一种机器学习范式,它通过组合多个模型的预测来提高整体模型的性能。单一模型可能在某些方面表现不佳或具有较高的偏差或方差,而集成方法能够通过结合多个模型的优点来克服这些问题,从而提…...
【CUDA】ubuntu环境下安装cuda
写在前面 软硬件匹配问题 :如老显卡安装ubuntu24, 会发现适合显卡的cuda不适合ubuntu24, 适合ubuntu24的cuda不适合显卡,因此安装ubuntu系统前,务必查明 :当前设备的显卡支持的cuda,支持哪些ubuntu版本 下面的三个问题…...
进程间通信-信号量
消息队列(Message Queue)是一种在不同组件或进程间进行异步通信的机制,它允许应用程序以松耦合的方式交换消息。消息队列就像一个缓冲区,发送者将消息放入队列,接收者从队列中取出消息进行处理。以下为你详细介绍消息队…...
Ubuntu 22.04安装MySQL : Qwen2.5 模型对话数据收集与微调教程
在Ubuntu 22.04安装MySQL的教程请点击下方链接进行参考: 点击这里获取MySQL安装教程 今天将为大家带来如何微调Qwen2.5模型并连接数据库进行对话的教程。快跟着小编一起试试吧~ 1 大模型 Qwen2.5 微调步骤 1.1 从 github 仓库 克隆项目 克隆存储库:#拉取代码 git clo…...
L1-8 新年烟花
单位 杭州百腾教育科技有限公司 新年来临,许多地方会举行烟花庆典庆祝。小 C 也想参加庆典,但不幸的是跟他一个想法的人实在太多,活动场地全是人人人人人人人人人…… 活动场地可视作一个 NM 的矩阵,其中有一些格子是空的&#…...
OpenCV中的轮廓检测方法详解
文章目录 引言一、什么是轮廓?二、OpenCV中的轮廓检测基础1. 基本步骤2. findContours函数详解 三、轮廓检索模式四、轮廓近似方法五、轮廓特征分析1. 轮廓面积2. 轮廓周长/弧长3. 轮廓近似(多边形拟合)4. 凸包5. 边界矩形6. 最小闭合圆7. 拟…...
AIP-231 批量方法:Get
编号231原文链接AIP-231: Batch methods: Get状态批准创建日期2019-06-18更新日期2019-06-18 一些API允许用户获取一组特定资源在一个时间点(例如使用读事务)的状态。批量获取方法提供了这个功能。 指南 API 可以 按照以下模式支持批量获取࿱…...
人工智能基础-matplotlib基础
绘制图形 import numpy as np x np.linspace(0, 10, 100) y np.sin(x) import matplotlib as mpl import matplotlib.pyplot as plt plt.plot(x, y) plt.show()绘制多条曲线 siny y.copy() cosy np.cos(x) plt.plot(x, siny) plt.plot(x, cosy) plt.show()设置线条颜色 …...
qt运行时报段错误
标题: qt运行时报段错误,查看stack,显示: 原因 报错的cpp文件新包含一个头文件,这个头文件里的pack指令有问题,如下: 解决办法 修改为正确的pack指令。...
【Qt】Qt Creator开发基础:项目创建、界面解析与核心概念入门
🍑个人主页:Jupiter. 🚀 所属专栏:QT 欢迎大家点赞收藏评论😊 目录 Qt Creator 新建项⽬认识 Qt Creator 界⾯项⽬⽂件解析Qt 编程注意事项认识对象模型(对象树)Qt 窗⼝坐标体系 Qt Creator 新…...
CAP应用
1.工作原理 CAP(Consistent,Available,Partition - tolerant)框架在.NET 中的工作原理。CAP 是一个用于.NET 的分布式事务解决方案,主要用于实现微服务架构中的数据一致性(实现分布式事务的最终一致性&…...
典型操作系统内核架构
在典型操作系统架构(如下图所示)中,内核负责以安全、公平的方式为多个应用程序管理和共享硬件资源。 内核通过一组 API(即系统调用)向应用程序提供服务。这些 API 不同于常规库函数,因其是用户模式到内核模…...
AWS Redshift的使用场景及一些常见问题
Redshift 不是关系型数据库, 提供了Amazon Redshift Serverless 和 Amazon Redshift 都是构建于 Redshift 数仓引擎之上的,但它们适用的场景不同。Redshift和Dynamodb都可以存储数据, 分别怎么选择? 这里记录一些常见的问题和场景。 1. 如何选择用Amazon Redshift…...
**searchProperties 是什么,python中**是什么:解包字典的操作符
searchProperties 是什么,python中是什么:解包字典的操作符 在 Python 中,** 是用于解包字典的操作符,**searchProperties 是一个可变关键字参数。它允许函数接受任意数量的关键字参数,这些参数会被收集到一个字典中,字典的键是参数名,值是参数对应的值。 在 ButtonCon…...
.NET MCP 文档
MCP 概述 MCP(Model Context Protocol)是由 Anthropic 推出的一种开放协议,类似 AI 的 USB-C 扩展坞,用于在大模型和数据源之间建立安全的通信(授权),让 AI 应用能够安全地访问和操作本地或远程…...
07软件测试需求分析案例-修改用户信息
修改用户信息是后台管理菜单的一个功能模块,只有admin才有修改权限。包括查询用户名进行显示用户相关信息,并且修改用户相关信息的功能。 1.1 通读文档 通读需求规格说明书是提取信息,提出问题,输出具有逻辑、规则、流程的业务…...
第九届“创客中国”中小企业创新创业大赛总决赛企业组三等奖项目—基于AI智能代码疫苗技术的数字供应链安全解决方案
项目名称:基于AI智能代码疫苗技术的数字供应链安全解决方案 企业名称:北京安普诺信息技术有限公司(悬镜安全) 项目简介: 基于AI智能代码疫苗技术的数字供应链安全解决方案,悬镜安全在全球范围内首创…...
企业级RAG行业应用落地方案——阿里云百炼
行业痛点分析 这张图主要围绕“行业痛点锚定”展开,通过雷达图和表格结合的方式,分析电商选品在不同维度下的情况: 分析对象:聚焦电商选品。维度展示:从可结构化程度、重复性、数据可得性、人机互动性、AI带来的价值这…...
Mac切换node版本
Mac切换node版本 1.首先安装n模块: sudo npm install -g n 2.升级node.js到最新稳定版 sudo n stable 3.升级到最新版 sudo n latest 4.n后面也可以跟随版本号,升级到任意版本 sudo n v0.10.26或sudo n 0.10.26 5.切换使用版本 sudo n 7.10.0 6.删除制定版本…...
从零开始学A2A一:A2A 协议概述与核心概念
A2A 协议概述与核心概念 学习目标 基础理解 掌握A2A协议的基本概念和背景理解协议的设计原则和核心思想了解协议在AI领域的重要性 技术掌握 熟悉A2A协议的核心功能组件掌握能力发现和任务管理机制理解多模态交互和安全通信原则 实践应用 能够设计基于A2A的智能体系统掌握协议…...
科普:如何通过ROC曲线,确定二分类的“理论阈值”
在二分类问题中,已知预测概率(如逻辑回归、神经网络输出的概率值)时,阈值的选择直接影响分类结果(正/负样本判定)。 一、实践中的阈值选择方法 1. 基于业务目标的调整 最大化准确率:适用于样…...
Cherry Studio + MCP,从0到1保姆教程,3个场景体验
📺 详细操作以视频方式呈现,视频地址周五会更新出来 💯 鉴于很多观众网络环境受限,文末提供所需安装文件网盘分享 💬 什么是 MCP ? MCP(Model Context Protocol,MCP)模型…...
Docker学习笔记-docker安装、删除
一、在centOS 7中docker的默认安装目录 # Docker 主配置文件目录 ls /etc/docker# Docker 数据目录(镜像、容器、卷等) ls /var/lib/docker# Docker 可执行文件路径 which docker # 输出类似 /usr/bin/docker 二、docker文件目录说明 目录/文件用途/…...
visual studio 常用的快捷键(已经熟悉的就不记录了)
以下是 Visual Studio 中最常用的快捷键分类整理,涵盖代码编辑、调试、导航等核心场景: 一、生成与编译 生成解决方案 Ctrl Shift B 一键编译整个解决方案,检查编译错误(最核心的生成操作)编译当前文件 Ctrl F…...
使用人工智能大模型腾讯元宝,如何做课题研究?
今天我们学习使用人工智能大模型腾讯元宝,如何做课题研究? 手把手学习视频地址:https://edu.csdn.net/learn/40402/666424 在腾讯元宝对话框中输入如何协助老师做课题(申报书、开题报告、中期报告、结题报告)&#x…...
开源模型应用落地-模型上下文协议(MCP)-第三方MCP Server实战指南(五)
一、前言 在AI技术高速发展的2025年,如何让大语言模型(LLM)更灵活地调用外部工具与数据,成为开发者关注的焦点。模型上下文协议(MCP)作为AI与外部资源的“万能接口”,通过标准化交互框架解决了传统集成中的碎片化问题。而第三方MCP Server的引入,进一步降低了开发门…...
python每日一练
题目一 输入10个整数,输出其中不同的数,即如果一个数出现了多次,只输出一次(要求按照每一个不同的数第一次出现的顺序输出)。 解题 错误题解 a list(map(int,input().split())) b [] b.append(a[i]) for i in range(2,11):if a[i] not in b:b.append(a[i]) print(b)但是会…...
跨境贸易之常见的贸易术语
外贸出口中经常会听到FOB、CIF、DDP各种术语,这些都是什么意思呢? 今天我们来介绍一下他们的确切含义。一般来说你听到的这些话语都是表示交货的方式。 如果普通的贸易过程大家一听就明白的,就是货到付款,款到发货,支…...
KingbaseES之KDts迁移SQLServer
项目适配迁移SQLServer至金仓,今天写写KDts-WEB版迁移工具迁移SQLServer至KingbaseES的步骤,以及迁移注意事项. SQLServer版本:SQLServer2012 KingbaseES版本:V009R004C011(SQLServer兼容版) --1.进入数据库客户端工具KDTS工具目录,启动KDts服务: [king…...
Rust编程学习(一): 变量与数据类型
我们先从Rust基本的变量声明定义与数据类型开始学习,了解这门语言基本特性。 1 变量与可变性 变量声明 变量声明以let关键字开头,x为变量名,变量名后紧跟冒号和数据类型,但是rust编译器有自动推导变量类型的功能,可以省略显式的声…...
Java 在人工智能领域的突围:从企业级架构到边缘计算的技术革新
一、Java AI 的底层逻辑:从语言特性到生态重构 在 Python 占据 AI 开发主导地位的当下,Java 正通过技术重构实现突围。作为拥有 30 年企业级开发经验的编程语言,Java 的核心优势在于强类型安全、内存管理能力和分布式系统支持,这…...
[极客大挑战 2019]HardSQL1
打开网页,貌似存在SLQ注入,尝试闭合单引号 才生报错信息,但是尝试联合注入 不出意外应该是被过滤了,没法使用,可以考虑一下报错注入 这里可以使用字典爆破一下,利用页面返回情况,看看哪些关键词…...
深入剖析C++中 String 类的模拟实现
目录 引言 一、基础框架搭建 成员变量与基本构造函数 析构函数 二、拷贝与赋值操作 深拷贝的拷贝构造函数 赋值运算符重载 三、字符串操作功能实现 获取字符串长度 字符串拼接 字符串比较 字符访问 四、迭代器相关实现(简单模拟) 迭代器类型…...
KWDB创作者计划— KWDB技术范式革命:从数据存储到认知进化的架构跃迁
引言:数据库的认知觉醒 在AIoT设备数量突破万亿、边缘计算节点算力总和超越云端的2025年,传统数据库的"存储-计算"二元结构正面临认知维度缺失的困境。当工业数字孪生需要实时推演百万设备状态,城市大脑需处理多模态时空数据时&…...