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

Android Framework 常见解决方案(25-1)定制CPUSET解决方案-framework部分修改

1 原理说明

这个方案有如下基本需求:

  • 构建自定义CPUSET,/dev/cpuset中包含一个全新的cpuset分组。且可以通过set_cpuset_policy和set_sched_policy接口可以设置自定义CPUSET。
  • 开机启动后可以通过zygote判定来对特定的应用进程设置CPUSET,并一直保持,且保证自定义CPUSET不受其他CPUSET影响,持续独立。

原理上因为修改代码涉及部分较多,因此共分3个部分:

  1. framework修改:添加SCHED GROUP和THREAD GROUP(THREAD_GROUP_对应SP_)的支持,且支持开机启动后直接设置。applyOomAdjLSP的判定保持不变。
  2. system修改:添加SP_CUSTOM的支持及set_cpuset_policy和set_sched_policy接口等支持,同时修改task_profiles.json,添加SP_CUSTOM CPUSET的支持。
  3. init.rc修改及编译部分调整:对自定义cpuset节点进行操作,vndk部分编译需要重新调整方案以及不修改VNDK如何保证编译通过。

由于修改中涉及代码量过大,这里拆分成两节进行展示。本章节主要针对第1部分修改进行说明。下一篇文章 👇

Android Framework 常见解决方案(25-2)定制CPUSET解决方案-system修改及编译部分调整

主要对第2和第3部分修改进行说明。

2 修改方案-framework部分(Android S)

这里需要添加THREAD_GROUP_CUSTOM,与system中修改的SP_CUSTOM同步,数值需一致,需要在$AOSP/frameworks/base/core/java/android/os/Process.java文件中修改:

public class Process {private static final String LOG_TAG = "Process";/*** An invalid UID value.*/public static final int INVALID_UID = -1;//.../*** Thread group for RT app.* @hide**/public static final int THREAD_GROUP_RT_APP = 6;/*** Thread group for bound foreground services that should* have additional CPU restrictions during screen off* @hide**/public static final int THREAD_GROUP_RESTRICTED = 7;/*** Thread Group for CUSTOM* @hide**/public static final int THREAD_GROUP_CUSTOM = 8;//...
}

接下来需要添加SCHED_GROUP_CUSTOM相关配置。在$AOSP/frameworks/base/services/core/java/com/android/server/am/ProcessList.java文件中修改:

public final class ProcessList {//...// Activity manager's version of Process.THREAD_GROUP_BACKGROUNDstatic final int SCHED_GROUP_BACKGROUND = 0;// Activity manager's version of Process.THREAD_GROUP_RESTRICTEDstatic final int SCHED_GROUP_RESTRICTED = 1;// Activity manager's version of Process.THREAD_GROUP_DEFAULTstatic final int SCHED_GROUP_DEFAULT = 2;// Activity manager's version of Process.THREAD_GROUP_TOP_APPpublic static final int SCHED_GROUP_TOP_APP = 3;// Activity manager's version of Process.THREAD_GROUP_TOP_APP// Disambiguate between actual top app and processes bound to the top appstatic final int SCHED_GROUP_TOP_APP_BOUND = 4;
+    //add custom schedule group
+    static final int SCHED_GROUP_CUSTOM = 10;//...private static boolean writeProcessOomListToProto(ProtoOutputStream proto, long fieldId,ActivityManagerService service, List<ProcessRecord> origList,boolean inclDetails, String dumpPackage) {//...switch (state.getSetSchedGroup()) {case SCHED_GROUP_BACKGROUND:schedGroup = ProcessOomProto.SCHED_GROUP_BACKGROUND;break;case SCHED_GROUP_DEFAULT:schedGroup = ProcessOomProto.SCHED_GROUP_DEFAULT;break;case SCHED_GROUP_TOP_APP:schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP;break;case SCHED_GROUP_TOP_APP_BOUND:schedGroup = ProcessOomProto.SCHED_GROUP_TOP_APP_BOUND;
+                case SCHED_GROUP_CUSTOM:
+                    schedGroup = ProcessOomProto.SCHED_GROUP_CUSTOM;
+                    break;}//...}//...private static boolean dumpProcessOomList(PrintWriter pw,ActivityManagerService service, List<ProcessRecord> origList,String prefix, String normalLabel, String persistentLabel,boolean inclDetails, String dumpPackage) {//...    for (int i = list.size() - 1; i >= 0; i--) {//...switch (state.getSetSchedGroup()) {case SCHED_GROUP_BACKGROUND:schedGroup = 'b';break;case SCHED_GROUP_DEFAULT:schedGroup = 'F';break;case SCHED_GROUP_TOP_APP:schedGroup = 'T';break;case SCHED_GROUP_RESTRICTED:schedGroup = 'R';break;case SCHED_GROUP_TOP_APP_BOUND:schedGroup = 'B';break;
+                case SCHED_GROUP_CUSTOM:
+                    schedGroup = 'C';
+                    break;default:schedGroup = '?';break;}}

添加SCHED_GROUP_CUSTOM,与ProcessList.java中同步。在$AOSP/frameworks/base/core/proto/android/server/activitymanagerservice.proto文件中修改:

//...
message ProcessOomProto {//...enum SchedGroup {SCHED_GROUP_UNKNOWN = -1;SCHED_GROUP_BACKGROUND = 0;SCHED_GROUP_DEFAULT = 1;SCHED_GROUP_TOP_APP = 2;SCHED_GROUP_TOP_APP_BOUND = 3;
+        SCHED_GROUP_CUSTOM = 10;}

 为适配之前的适配SP_CUSTOM,同时契合之前1中修改的task_profile.json文件中的配置,在AOSP/frameworks/base/core/jni/android_util_Process.cpp文件中修改:

//修改android_os_Process_setProcessGroup,适配SP_CUSTOM
void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
{ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp);//...while ((de = readdir(d))) {//...// grp != SP_BACKGROUND. Only change the cpuset cgroup for low priority thread, so it could// preserve it sched policy profile setting.if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {switch (grp) {case SP_SYSTEM:taskprofile = "ServiceCapacityLow";break;case SP_RESTRICTED:taskprofile = "ServiceCapacityRestricted";break;case SP_FOREGROUND:case SP_AUDIO_APP:case SP_AUDIO_SYS:taskprofile = "ProcessCapacityHigh";break;case SP_TOP_APP:taskprofile = "ProcessCapacityMax";break;
+                case SP_CUSTOM:
+                    taskprofile = "CustomPerformance";
+                    break;default:taskprofile = "ProcessCapacityNormal";break;}if (!SetTaskProfiles(t_pid, {taskprofile}, true)) {signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);break;}// Change the cpuset policy profile for non-low priority thread according to the grp} else {if (!SetTaskProfiles(t_pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}, true)) {signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);break;}}}closedir(d);
}//修改get_cpuset_cores_for_policy,适配SP_CUSTOM
static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set)
{FILE *file;std::string filename;CPU_ZERO(cpu_set);switch (policy) {case SP_BACKGROUND:if (!CgroupGetAttributePath("LowCapacityCPUs", &filename)) {return;}break;case SP_FOREGROUND:if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {return;}break;case SP_AUDIO_APP:case SP_AUDIO_SYS:if (!CgroupGetAttributePath("AudioAppCapacityCPUs", &filename)) {return;}if (access(filename.c_str(), F_OK) != 0) {if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {return;}}break;case SP_RT_APP:if (!CgroupGetAttributePath("HighCapacityCPUs", &filename)) {return;}break;case SP_TOP_APP:if (!CgroupGetAttributePath("MaxCapacityCPUs", &filename)) {return;}break;
+        case SP_CUSTOM:
+            if (!CgroupGetAttributePath("CustomCPUs", &filename)) {
+                return;
+            }
+            break;default:return;}file = fopen(filename.c_str(), "re");if (file != NULL) {// Parse cpus stringchar *line = NULL;size_t len = 0;ssize_t num_read = getline(&line, &len, file);fclose (file);if (num_read > 0) {parse_cpuset_cpus(line, cpu_set);} else {ALOGE("Failed to read %s", filename.c_str());}free(line);}return;
}

在这里使用com.ags.test应用demo进行测试后验证。根据自己需要调整即可。主要保证该应用始终在SCHED_GROUP_CUSTOM中,不切换到其它schedule group中,同时建立SCHED_GROUP_CUSTOM和THREAD_GROUP_CUSTOM之间的联系。在$AOSP/frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java文件中修改:

//...
+import static android.os.Process.THREAD_GROUP_CUSTOM;
//...
public class OomAdjuster {//...private boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now,long nowElapsed) {boolean success = true;final ProcessStateRecord state = app.mState;if (state.getCurRawAdj() != state.getSetRawAdj()) {state.setSetRawAdj(state.getCurRawAdj());}//...int processGroup;switch (curSchedGroup) {case ProcessList.SCHED_GROUP_BACKGROUND:processGroup = THREAD_GROUP_BACKGROUND;break;case ProcessList.SCHED_GROUP_TOP_APP:case ProcessList.SCHED_GROUP_TOP_APP_BOUND:processGroup = THREAD_GROUP_TOP_APP;break;case ProcessList.SCHED_GROUP_RESTRICTED:processGroup = THREAD_GROUP_RESTRICTED;break;
+                    case ProcessList.SCHED_GROUP_CUSTOM:
+                        processGroup = THREAD_GROUP_CUSTOM;
+                        break;default:processGroup = THREAD_GROUP_DEFAULT;break;}//...}//...private boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj,ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval,boolean computeClients) {//...
+        if(app.processName.equals("com.ags.test")){
+            schedGroup = ProcessList.SCHED_GROUP_CUSTOM;
+        }// Do final modification to adj.  Everything we do between here and applying// the final setAdj must be done in this function, because we will also use// it when computing the final cached adj later.  Note that we don't need to// worry about this for max adj above, since max adj will always be used to// keep it out of the cached vaues.state.setCurAdj(psr.modifyRawOomAdj(adj));state.setCurCapability(capability);state.setCurrentSchedulingGroup(schedGroup);state.setCurProcState(procState);state.setCurRawProcState(procState);state.updateLastInvisibleTime(hasVisibleActivities);state.setHasForegroundActivities(foregroundActivities);state.setCompletedAdjSeq(mAdjSeq);// if curAdj or curProcState improved, then this process was promotedreturn state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState|| state.getCurCapability() != prevCapability;}//... 
}

修改SpecializeCommon,主要是在创建进程时直接设置cpuset,在$AOSP/frameworks/base/core/jni/android_util_Process.cpp文件中修改:

static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags,jobjectArray rlimits, jlong permitted_capabilities,jlong effective_capabilities, jint mount_external,jstring managed_se_info, jstring managed_nice_name,bool is_system_server, bool is_child_zygote,jstring managed_instruction_set, jstring managed_app_data_dir,bool is_top_app, jobjectArray pkg_data_info_list,jobjectArray allowlisted_data_info_list, bool mount_data_dirs,bool mount_storage_dirs) {const char* process_name = is_system_server ? "system_server" : "zygote";auto fail_fn = std::bind(ZygoteFailure, env, process_name, managed_nice_name, _1);auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1);//...if (setresgid(gid, gid, gid) == -1) {fail_fn(CREATE_ERROR("setresgid(%d) failed: %s", gid, strerror(errno)));}// Must be called when the new process still has CAP_SYS_ADMIN, in this case,// before changing uid from 0, which clears capabilities.  The other// alternative is to call prctl(PR_SET_NO_NEW_PRIVS, 1) afterward, but that// breaks SELinux domain transition (see b/71859146).  As the result,// privileged syscalls used below still need to be accessible in app process.SetUpSeccompFilter(uid, is_child_zygote);// Must be called before losing the permission to set scheduler policy.SetSchedulerPolicy(fail_fn, is_top_app);+    if (nice_name.has_value()) {
+        if(strncmp(nice_name.value().c_str(),"com.ags.test",sizeof("com.ags.test"))==0){
+#if 1 //set_cpuset_policy方案
+            int ret = set_cpuset_policy(0, SP_CUSTOM);
+            if (ret != 0) {
+                ALOGE("set_cpuset_policy call default failure,ret:%d,(%s)", ret,nice_name.value().c_str());
+            }else{
+                ALOGD("set_cpuset_policy call default success,ret==0,(%s)", nice_name.value().c_str());
+            }
+#else //set_sched_policy兼容方案
+            int ret = set_sched_policy(0, SP_CUSTOM);
+            if (ret != 0) {
+                ALOGE("set_sched_policy call default failure,ret:%d,(%s)", ret,nice_name.value().c_str());
+            }
+           else{
+               ALOGD("set_sched_policy call default success,ret==0,(%s)", nice_name.value().c_str());
+            }
+#endif
+        }
+    }//...}

至此,framework层相关修改就结束了。主要添加SCHED_GROUP_CUSTOM、THREAD_GROUP_CUSTOM(THREAD_GROUP_对应SP_)即以和对应SP_CUSTOM之间的联系建立,且支持开机启动后直接过滤包,进行CPUSET的设置。同时applyOomAdjLSP的判定保持不变,不受其他CPUSET的影响。

相关文章:

Android Framework 常见解决方案(25-1)定制CPUSET解决方案-framework部分修改

1 原理说明 这个方案有如下基本需求&#xff1a; 构建自定义CPUSET&#xff0c;/dev/cpuset中包含一个全新的cpuset分组。且可以通过set_cpuset_policy和set_sched_policy接口可以设置自定义CPUSET。开机启动后可以通过zygote判定来对特定的应用进程设置CPUSET&#xff0c;并…...

PyTorch 参数化深度解析:自定义、管理和优化模型参数

目录 torch.nn子模块parametrize parametrize.register_parametrization 主要特性和用途 使用场景 参数和关键字参数 注意事项 示例 parametrize.remove_parametrizations 功能和用途 参数 返回值 异常 使用示例 parametrize.cached 功能和用途 如何使用 示例…...

自承载 Self-Host ASP.NET Web API 1 (C#)

本教程介绍如何在控制台应用程序中托管 Web API。 ASP.NET Web API不需要 IIS。 可以在自己的主机进程中自托管 Web API。 创建控制台应用程序项目 启动 Visual Studio&#xff0c;然后从“开始”页中选择“新建项目”。 或者&#xff0c;从“ 文件 ”菜单中选择“ 新建 ”&a…...

Vue2-子传父和父传子的基本用法

在Vue 2中&#xff0c;可以使用props和$emit来实现子组件向父组件传值&#xff08;子传父&#xff09;和父组件向子组件传值&#xff08;父传子&#xff09;。 子传父&#xff08;子组件向父组件传值&#xff09;的基本用法如下&#xff1a; 在父组件中定义一个属性&#xff…...

使用numpy处理图片——镜像翻转和旋转

在《使用numpy处理图片——基础操作》一文中&#xff0c;我们介绍了如何使用numpy修改图片的透明度。本文我们将介绍镜像翻转和旋转。 镜像翻转 上下翻转 from PIL import Image import numpy as np img Image.open(example.png) data np.array(img)# axis0 is vertical, a…...

HTML5 article标签,<time>...</time>标签和pubdate属性的运用

1、<article>...</article>标签的运用 article标签代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。它可以是一篇博客或报竟杂志中的文章、一篇论坛帖子、一段用户评论或一个独立的插件&#xff0c;或者其他任何独立的内容。把文章正文放在h…...

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

分享一个有趣的小工具&#xff0c;10MB 身材的小工具&#xff0c;能够将各种不同的模型 API 转换为开箱即用的 OpenAI API 格式。 让许多依赖 OpenAI API 的软件能够借助开发者能够接触到的&#xff0c;非 OpenAI 的 API 私有部署和使用起来。 写在前面 这个小工具软件写于两…...

RK3568平台开发系列讲解(驱动篇)pinctrl 函数操作集结构体讲解

🚀返回专栏总目录 文章目录 一、pinctrl_ops二、pinmux_ops三、pinconf_ops沉淀、分享、成长,让自己和他人都能有所收获!😄 pinctrl_ops:提供有关属于引脚组的引脚的信息。pinmux_ops:选择连接到该引脚的功能。pinconf_ops:设置引脚属性(上拉,下拉,开漏,强度等)。…...

vue购物车案例,v-model 之 lazy、number、trim,与后端交互

购物车案例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script src"./js/vue.js"></script> </head> <body> <div id"d1"&…...

云原生Kubernetes: Kubeadm部署K8S 1.29版本 单Master架构

目录 一、实验 1.环境 2.K8S master节点环境准备 3.K8S master节点安装kubelet、kubeadm、kubectl 3.K8S node节点环境准备与软件安装 4.K8S master节点部署服务 5.K8S node节点部署 6.K8S master节点查看集群 7.容器网络&#xff08;CNI&#xff09;部署 8.K8S 集群…...

C++协程操作

什么是C++协程 C++中的协程是一种用户态轻量级线程,它拥有自己的上下文和栈,并且协程的切换和调度由用户定义,不需要陷入内核。如同一个进程可以拥有多个线程,一个线程也可以拥有多个协程。协程的优点在于极高的执行效率,因为协程切换不需要陷入内核,而是由用户程序定义切…...

计算机配件杂谈-鼠标

目录 基础知识鼠标的发展鼠标的左右手鼠标的显示样式鼠标的移动和可见性移动可见性 现在的我们的生活工作都基本上离不开电脑了&#xff0c;不管是你平时玩玩游戏&#xff0c;上班工作等等&#xff1b; 今天将关于鼠标的一些小的技巧分享出来&#xff0c;共勉&#xff01; 基础…...

用Python来制作一个微信聊天机器人

1. 效果展示 通过本地搭建一个flask服务器来接收信息&#xff0c;这里我简单使用展示&#xff0c;就没有对接收的信息进行处理了。 信息接收展示 发送信息展示 这里就直接使用python发送一个post请求即可&#xff0c;可以发送文字或者图片 代码展示 接收信息 #!/usr/bin/e…...

2024年第九届机器学习技术国际会议(ICMLT 2024) 即将召开

2024年第九届机器学习技术国际会议&#xff08;ICMLT 2024&#xff09;将于2024年5月24-26日在挪威奥斯陆举行。ICMLT 2024旨在讨论机器学习技术领域的最新研究技术现状和前沿趋势&#xff0c;为来自世界各地的科学家、工程师、实业家、学者和其他专业人士提供一个互动和交流的…...

算法训练day9Leetcode232用栈实现队列225用队列实现栈

今天学习的文章和视频链接 https://programmercarl.com/%E6%A0%88%E4%B8%8E%E9%98%9F%E5%88%97%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 栈与队列理论基础 见我的博客 https://blog.csdn.net/qq_36372352/article/details/135470438?spm1001.2014.3001.5501 232用栈实现…...

linux驱动(四):platform

本文主要探讨x210驱动的平台设备类型(platform)以及misc设备。 驱动模型 设备驱动模型&#xff1a;总线(bus type)、设备(device)和驱动(driver) 总线&#xff1a;虚拟总线用于挂接驱动驱动和设备 总线、设备、驱动关系&#xff1a;/sys/bus下的子目录…...

Guava:Cache强大的本地缓存框架

Guava Cache是一款非常优秀的本地缓存框架。 一、 经典配置 Guava Cache 的数据结构跟 JDK1.7 的 ConcurrentHashMap 类似&#xff0c;提供了基于时间、容量、引用三种回收策略&#xff0c;以及自动加载、访问统计等功能。 基本的配置 Testpublic void testLoadingCache() th…...

#{}和${}的区别?

#{}是占位符&#xff0c;预编译处理&#xff1b;${}是拼接符&#xff0c;字符串替换&#xff0c;没有预编译处理。Mybatis在处理#{}时&#xff0c;#{}传入参数是以字符串传入&#xff0c;会将SQL中的#{}替换为?号&#xff0c;调用PreparedStatement的set方法来赋值。Mybatis在…...

string的模拟实现

string的模拟实现 msvc和g下的string内存比较成员变量构造函数与析构函数拷贝构造函数赋值拷贝c_str、size和capacity函数以及重载[]、clear、expand_capacity迭代器与遍历reservepush_back、append、insert字符串比较运算符erase<<流提取 >>流插入resizefindsubst…...

算法练习:查找二维数组中的目标值

题目&#xff1a; 编写一个高效的算法来搜索矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a;每行的元素从左到右升序排列。每列的元素从上到下升序排列。 实现&#xff1a; 1. main方法 public static void main(String[] args) {int[][] matrix {{1…...

考研自命题资料、考题如何找

这篇文章是抖音和b站上上传的同名视频的原文稿件&#xff0c;感兴趣的csdn用户可以关注我的抖音和b站账号&#xff08;GeekPower极客力量&#xff09;。同时这篇文章也为视频观众提供方便&#xff0c;可以更加冷静地分析和思考。文章同时在知乎发表。 去年我发布了一个视频&am…...

MySQL 存储引擎和索引类型介绍

1. 引言 MySQL 是一个流行的关系型数据库管理系统&#xff0c;提供多种存储引擎以满足不同的业务需求。本文将介绍几种常见的 MySQL 存储引擎和索引类型比较&#xff0c;并给出相应的示例。 2. 存储引擎概述 2.1 InnoDB 存储引擎 InnoDB 是 MySQL 的默认存储引擎&#xff0…...

element-ui table height 属性导致界面卡死

问题: 项目上&#xff0c;有个点击按钮弹出抽屉的交互, 此时界面卡死 原因分析: 一些场景下(父组件使用动态单位/弹窗、抽屉中使用), element-ui 的 table 会循环计算高度值, 导致界面卡死 github 上的一些 issues 和解决方案: Issues ElemeFE/element GitHub 官方讲是升…...

Vue2.v-指令

v-if 在双引号中写判断条件。 <div v-if"score>90">A</div> <div v-else-if"score>80">B</div> <div v-else>C</div>v-on: :冒号后面跟着事件。 为了简化&#xff0c;可以直接用代替v-on:。 事件名“内联语…...

Java中SpringBoot组件集成接入【Knife4j接口文档(swagger增强)】

Java中SpringBoot组件集成接入【Knife4j接口文档】 1.Knife4j介绍2.maven依赖3.配置类4.常用注解使用1.实体类及属性(@ApiModel和@ApiModelProperty)2.控制类及方法(@Api、@ApiOperation、@ApiImplicitParam、 @ApiResponses)3.@ApiOperationSupport注解未生效的解决方法5.…...

继承和多态的详解

文章目录 1. 继承1.1 继承的概念1.3 继承的语法1.3 父类成员访问1.3.1 子类中访问父类的成员变量1.3.2 子类中访问父类的成员方法 1.4 子类构造方法 2.super关键字2.1 super关键字的概念2.2 super和this的区别 3. 在继承中访问限定符的可见性4. 继承方式的分类5. 多态5.1 多态的…...

【Unity】UniTask(异步工具)快速上手

UniTask(异步工具) 官方文档&#xff1a;https://github.com/Cysharp/UniTask/blob/master/README_CN.md URL:https://github.com/Cysharp/UniTask.git?pathsrc/UniTask/Assets/Plugins/UniTask 优点&#xff1a;0GC&#xff0c;可以在任何地方使用 为Unity提供一个高性能&…...

k8s三种常用的项目发布方式

k8s三种常用的项目发布方式 1、 蓝绿发布 2、 金丝雀发布(灰度发布)&#xff1a;使用最多 3 、滚动发布 应用程序升级&#xff0c;面临的最大问题是新旧业务之间的切换。 项目的生命周期&#xff1a;立项----定稿----需求发布----开发----测试-----发布 最后测试之后上线。再…...

Nodejs搭配axios下载图片

新建一个文件夹&#xff0c;npm i axios 实测发现只需保留node_modules文件夹&#xff0c;删除package.json不影响使用 1.纯下载图片 其实该方法不仅可以下载图片&#xff0c;其他的文件都可以下载 const axios require(axios) const fs require(fs) var arrPic [https:…...

强化学习在生成式预训练语言模型中的研究现状简单调研

1. 绪论 本文旨在深入探讨强化学习在生成式预训练语言模型中的应用&#xff0c;特别是在对齐优化、提示词优化和经验记忆增强提示词等方面的具体实践。通过对现有研究的综述&#xff0c;我们将揭示强化学习在提高生成式语言模型性能和人类对话交互的关键作用。虽然这些应用展示…...

市桥做网站/百度一下移动版首页

1. 系统版本 MySQL 5.7.25 ubuntu 16.04 2. 全局锁 全局锁即对整个数据库实例加锁&#xff0c;使得整个库处于只读状态&#xff0c;会阻塞DML和DDL语句。使用如下命令&#xff08;简称FTWRL&#xff09;可为数据库加全局锁&#xff1a;flush tables with read lock;释放全局锁命…...

政府网站建设参考书/网络营销的公司有哪些

转眼间学习和使用C已经有近10个年头了&#xff0c;开始学习的时候走了不少的弯路&#xff0c;今天有些时间&#xff0c;希望写下这篇文章并且对开始学习C的朋友有些帮助。当然我首先需要说明的是&#xff0c;这篇文章是根据本人的感受写的&#xff0c;可能不同的人有不同的观点…...

做网站买别人的服务器/网络推广岗位职责和任职要求

已读完&#xff0c;待扫描笔记内容复制上来。并找到一个手机应用程序&#xff1a;aTimelogger非常好用。朋友写的文章&#xff1a;给你的时间记记账-aTimeLogger2软件使用心得试着记录自己的主要工作和生活学习内容的用时。此图做的非常不满意。不好。...

网站被篡改怎样做/互联网营销策划是做什么的

Codeforces Round #618 (Div. 2) A做的还是不快 卡了一下B 果断开了C 然后回头发现B怎么过的人这么多 就想到了 最后抄板子过了D 一度以为能直接到蓝 熬了两个小时想看颜色变化 顶不死睡了起床发现只涨了100 而且也没有以前有过的涨很多分的congratulation A 题意&#xff1a…...

网站备案后怎么做实名认证/播放量自助下单平台

在学习UCOS过程中&#xff0c;想通过串口中断将接收到的数据放到消息队列中去&#xff0c;编写代码如下&#xff1a;#include "led.h"#include "delay.h"#include "key.h"#include "sys.h"#include "usart.h"#include "…...

给传销做网站/网络营销的好处和优势

在 Android 所有的控件和 Layout 都有着一个父类 View 。Anroid 通过继承的方式&#xff0c;对父类控件进行继承&#xff0c;由此来在父类基础上创造新的控件。View我们先看看 View 这个父类Paste_Image.png可以看到间接继承的有100多个子类&#xff0c;不得不说 View 这个爹很…...