(一)启动进程Init

init进程【1】——init启动过程 众所周知,Linux中的所有进程都是有init进程创建并运行的。首先Linux内核启动,然后在用户空间中启动init进程,再启动其他系统进程。在系统启动完成完成后,init将变为守护进程监视系统其他进程。Android是基于Linux的操作系统,所以init也是Android系统中用户空间的第一个进程,它的进程号是1。下面先简单的看一下init进程的启动过程。 @/kernel/good 阅读详情

系统启动的整体流程

一、Init进程元认知

init进程是用户级的第一个进程(UserPlace)
在Linux中所有进程都是init的子进程,Linux中一切都是以文件的形式存在的,主要提供四大功能

  • 建立文件所在目录
  • 挂载设备
  • 处理Action

    职责关注部分:
    创建zygote进程
    启动属性服务
    性能分析(BootChart)
    无线循环(启动其他的进程)

二、init代码部分

init进程的入口函数是main,它的代码如下所示:

[-->init.c]

int main(int argc, char **argv)

{

    intdevice_fd = -1;

    intproperty_set_fd = -1;

    intsignal_recv_fd = -1;

    intkeychord_fd = -1;

    int fd_count;

    ints[2];

    intfd;

    structsigaction act;

    chartmp[PROP_VALUE_MAX];

    structpollfd ufds[4];

    char*tmpdev;

    char*debuggable;



   //设置子进程退出的信号处理函数,该函数为sigchld_handler。

   act.sa_handler = sigchld_handler;

    act.sa_flags= SA_NOCLDSTOP;

   act.sa_mask = 0;

   act.sa_restorer = NULL;

   sigaction(SIGCHLD, &act, 0);



   **......//创建一些文件夹,并挂载设备,这些是和Linux相关的,不拟做过多讨论。**

   mkdir("/dev/socket", 0755);

   mount("devpts", "/dev/pts", "devpts", 0,NULL);

   mount("proc", "/proc", "proc", 0, NULL);

   mount("sysfs", "/sys", "sysfs", 0, NULL);



    //重定向标准输入/输出/错误输出到/dev/_null_。

open_devnull_stdio();

/*

设置init的日志输出设备为/dev/__kmsg__,不过该文件打开后,会立即被unlink了,

这样,其他进程就无法打开这个文件读取日志信息了。

*/

   log_init();



   //上面涉及很多和Linux系统相关的知识,不熟悉的读者可自行研究,它们不影响我们的分析

   ****//解析init.rc配置文件****

   parse_config_file("/init.rc");



    ......

    //下面这个函数通过读取/proc/cpuinfo得到机器的Hardware名,我的HTCG7手机为bravo。

   get_hardware_name();

snprintf(tmp,sizeof(tmp), "/init.%s.rc", hardware);

//解析这个和机器相关的配置文件,我的G7手机对应文件为init.bravo.rc。

   parse_config_file(tmp);



/*

解析完上述两个配置文件后,会得到一系列的Action(动作),下面两句代码将执行那些处于

early-init阶段的Action。init将动作执行的时间划分为四个阶段:early-init、init、

early-boot、boot。由于有些动作必须在其他动作完成后才能执行,所以就有了先后之分。哪些

动作属于哪个阶段由配置文件决定。后面会介绍配置文件的相关知识。

*/

   action_for_each_trigger("early-init", action_add_queue_tail);

   drain_action_queue();



/*

创建利用Uevent和Linux内核交互的socket。关于Uevent的知识,第9章中对

Vold进行分析时会做介绍。

    */

   device_fd = device_init();

    **//初始化和属性相关的资源
property_init();**

//初始化/dev/keychord设备,这和调试有关,本书不讨论它的用法。读者可以自行研究,

//内容比较简单。

   keychord_fd = open_keychord();



    ......

/*

  INIT_IMAGE_FILE定义为”/initlogo.rle”,下面这个函数将加载这个文件作为系统的开机

 画面,注意,它不是开机动画控制程序bootanimation加载的开机动画文件。

*/

if(load_565rle_image(INIT_IMAGE_FILE) ) {

   /*

如果加载initlogo.rle文件失败(可能是没有这个文件),则会打开/dev/ty0设备,并

输出”ANDROID”的字样作为开机画面。在模拟器上看到的开机画面就是它。

*/

      ......

      }

   }



    if(qemu[0])

       import_kernel_cmdline(1);

   ......

//调用property_set函数设置属性项,一个属性项包括属性名和属性值。

   property_set("ro.bootloader", bootloader[0] ? bootloader :"unknown");



    ......//执行位于init阶段的动作

   action_for_each_trigger("init", action_add_queue_tail);

   drain_action_queue();



    **//启动属性服务**

   property_set_fd = start_property_service();



/*

调用socketpair函数创建两个已经connect好的socket。socketpair是Linux的系统调用,

不熟悉的读者可以利用man socketpair查询相关信息。后面就会知道它们的用处了。

*/

    if(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {

       signal_fd = s[0];

       signal_recv_fd = s[1];

        ......

    }



    ......



    //执行配置文件中early-boot和boot阶段的动作。

   action_for_each_trigger("early-boot", action_add_queue_tail);

   action_for_each_trigger("boot", action_add_queue_tail);

   drain_action_queue();

......    



//init关注来自四个方面的事情。

    ufds[0].fd= device_fd;//device_fd用于监听来自内核的Uevent事件

   ufds[0].events = POLLIN;

   ufds[1].fd = property_set_fd;//property_set_fd用于监听来自属性服务器的事件

ufds[1].events= POLLIN;

//signal_recv_fd由socketpair创建,它的事件来自另外一个socket。

   ufds[2].fd = signal_recv_fd;

   ufds[2].events = POLLIN;

   fd_count = 3;

if(keychord_fd > 0) {

   //如果keychord设备初始化成功,则init也会关注来自这个设备的事件。

       ufds[3].fd = keychord_fd;

       ufds[3].events = POLLIN;

       fd_count++;

}

......



#if BOOTCHART

    ......//与Boot char相关,不做讨论了。

/*

Boot chart是一个小工具,它能对系统的性能进行分析,并生成系统启动过程的图表,

以提供一些有价值的信息,而这些信息最大的用处就是帮助提升系统的启动速度。

    */

#endif

  for(;;) {

        **//从此init将进入一个无限循环。**

       int nr, i, timeout = -1;



       for (i = 0; i < fd_count; i++)

           ufds[i].revents = 0;



        //在循环中执行动作

       drain_action_queue();

       restart_processes(); //重启那些已经死去的进程

......

#if BOOTCHART

        ...... // Boot Chart相关

#endif

        //调用poll等待一些事情的发生

        nr= poll(ufds, fd_count, timeout);

       ......

       //ufds[2]保存的是signal_recv_fd,用于接收来自socket的消息。

        if(ufds[2].revents == POLLIN) {

           //有一个子进程去世,init要处理这个事情

            read(signal_recv_fd, tmp, sizeof(tmp));

           while (!wait_for_one_process(0))

               ;

           continue;

        }



        if(ufds[0].revents == POLLIN)

           handle_device_fd(device_fd);//处理Uevent事件

        if(ufds[1].revents == POLLIN)

           handle_property_set_fd(property_set_fd);//处理属性服务的事件。

        if(ufds[3].revents == POLLIN)

           handle_keychord(keychord_fd);//处理keychord事件。

    }



    return0;

}

1.1 入口函数Main

  1. 初始化(/der.proc/目录,执行init.rc 解析配置文件)
  2. void部分 Uevent 与linux交互Socket
  3. for循环(守护进程 信号量)

1.1.1 解析配置文件init.rc
还有一个rc文件是xx.rc(xx是硬件名),这个文件只是系统的一个镜像文件,更改也没有用。如想改变则需要在boot.ing核镜像中修改。有一个函数parseconfig函数进行解析,其中有一个Section Zygote被放在一个Service中。
1.1.2 解析规则
使用的是Android Init Language 编译的脚本
分为 :

  1. Action (一组被命名的Command序列)
  2. Command 五种语句类型
  3. Service 由init进程启动或重启的程序
  4. Options Services 修饰词 ,指定如何并何时启动
  5. Import

一个Section 的结构一般是:

on  <trigger>
      <command>
      <command>
service <name> <pathname> [ <argument> ]*

#是注释 ,on init 和 onboot是Action类型。
解析rc文件的详细内容:
http://blog.youkuaiyun.com/yangwen123/article/details/9029959

1.1.3解析Service
init中使用一个结构体来保存Service Section 相关信息(使用Socket,action结构体) 函数ParseService 搭建一个servce的架子。
Parse_line_service 将根据配置文件的内容填完service结构体
zygote 解析后的结果:service List 将解析后的Service全部连在一起。
Socketinifo -> Socket链表
onrestart commands 指向一个 Commands 链表

1.1.4 init控制service
其中sygote 就是在其中一个Service中
在rc 文件中一个service

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server  
    class main  
    socket zygote stream 660 root system  
    onrestart write /sys/android_power/request_state wake  
    onrestart write /sys/power/state on  
    onrestart restart media  
    onrestart restart netd  

class_start default ->是一个COMMAND 位于boot(引导) section 范围内。
最后执行service_start函数,并在启动前要判断可执行文件,是否存在 /system/bin/applprocress
主要做了以下几个工作:

  1. 调用fork()系统调用创建新的进程;
  2. 获取属性匿名存储空间句柄,并添加为服务配置的环境变量;
  3. 创建服务配置的socket,调用publish_socket函数将创建的socket句柄添加到环境变量中;该环境变量为:ANDROID_SOCKET_XXX
    = fd
  4. 为新进程打开控制台,并设置新进程的PID,GID等;
  5. 调用execve()系统调用执行新进程运行的程序;
  6. 设置服务运行状态属性;该属性为:init.svc.XXX = running

1.1.5 重启Zygote
onrestart是在zygote重启时用的,当内存不足时,Android系统会自动杀死一下进程来释放空间,所以当某些重要的服务被杀,同时该服务进程并未设置为oneshot,则必须重新启动该服务进程。
zygote死后父进程init 会通过Socket接收数据执行代码(Main函数中)->init.rc.main中工作如下:

static int wait_for_one_process(int block)  
{   //block = 0 -->false  
    pid_t pid;  
    int status;  
    struct service *svc;  
    struct socketinfo *si;  
    time_t now;  
    struct listnode *node;  
    struct command *cmd;  
    /*当进程被终止时,将发送SIGCHLD信号,waitpid()函数用来回收进程所占用的资源,第一个参 
    数pid是指欲等待的子进程的识别码,设置为-1表示查看所有子进程是否发出SIGCHIL信号,第二 
    个参数status用于返回子进程的结束状态;第三个参数决定waitpid()函数是否应用阻塞处理方式。 
    waitpid()函数返回产生SIGCHID信号的进程pid */  
    while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR );  
    //正常情况下返回的死亡进程pid大于0,因此wait_for_one_process的返回值正常情况下为0  
    if (pid <= 0) return -1;  
    INFO("waitpid returned pid %d, status = %08x\n", pid, status);  
    //用于根据pid值在服务链表中查找对应的服务  
    svc = service_find_by_pid(pid);  
    if (!svc) {  
        ERROR("untracked pid %d exited\n", pid);  
        return 0;  
    }  

    NOTICE("process '%s', pid %d exited\n", svc->name, pid);  
    /* 检查服务是否设置了oneshot标志,SVC_ONESHOT表示进程仅运行一次,如果没有设置SVC_ONESHOT标志, 
    表示需要重启该服务进程,首先将该服务进程组下的所有子进程杀死 */  
    if (!(svc->flags & SVC_ONESHOT)) {  
        kill(-pid, SIGKILL);  
        NOTICE("process '%s' killing any children in process group\n", svc->name);  
    }  

    /* 删除该服务进程下的创建的所有socket  */  
    for (si = svc->sockets; si; si = si->next) {  
        char tmp[128];  
        snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);  
        unlink(tmp);  
    }  
    //设置服务的pid为0 ,并清除SVC_RUNNING标志  
    svc->pid = 0;  
    svc->flags &= (~SVC_RUNNING);  

    /* 如果设置了SVC_ONESHOT标志,表示服务只能运行一次,因此设置表示位SVC_DISABLED */  
    if (svc->flags & SVC_ONESHOT) {  
        svc->flags |= SVC_DISABLED;  
    }  

    /* 判断服务标志是否设置了SVC_DISABLED 或 SVC_RESET 对于设置了这两种标志的进程是不能重启的 */  
    if (svc->flags & (SVC_DISABLED | SVC_RESET) )  {  
        //设置进程运行状态属性值为stopped  
        notify_service_state(svc->name, "stopped");  
        return 0;  
    }  

    now = gettime();  
    //如果死亡的服务进程是系统关键进程,则直接重启手机  
    if (svc->flags & SVC_CRITICAL) {  
        if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {  
            if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {  
                ERROR("critical process '%s' exited %d times in %d minutes; "  
                      "rebooting into recovery mode\n", svc->name,  
                      CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60);  
                //手机重启  
                android_reboot(ANDROID_RB_RESTART2, 0, "recovery");  
                return 0;  
            }  
        } else {  
            svc->time_crashed = now;  
            svc->nr_crashed = 1;  
        }  
    }  
    //设置服务进程标志SVC_RESTARTING,在restart_processes()函数中会重启持有SVC_RESTARTING  
    svc->flags |= SVC_RESTARTING;  

    /* 运行该service下所有Execute all onrestart commands for this service. */  
    list_for_each(node, &svc->onrestart.commands) {  
        cmd = node_to_item(node, struct command, clist);  
        cmd->func(cmd->nargs, cmd->args);   
    }  
    //设置进程运行状态属性值为stopped  
    notify_service_state(svc->name, "restarting");  
    return 0;  
}  
  1. 找到死service
  2. 杀掉zygote创建的所有子进程
  3. 清除socket信息
  4. 如果实质SVC_CRIICAL标志位则4分钟内不超过4次否则进入(recovery模式)

1.2属性服务(ProPerty_Service)

系统应用程序将会存储一些属性进入属性表中。即时系统重启,注册表应用程序重启,也能初始化。
property_service (属性服务机制)(socket服务)
属性文件是一些位列于不同目录,系统依次读取的配置文件。
1.启动(Socket服务)
init.c文件中函数()与属性服务有关的代码
property_init();
property_set_fd=start_property_service();

1.2.1 属性服务的初始化
在前面分析main函数时涉及到一个property_init函数,该函数调用了init_property_area函数,该函数用于初始化属性内存区域,也就是system_property_area变量。
这个函数加载defaut.prop文件(属性文件)
虽然init进程创建但希望其他进程也能读到内存中的东西,于是做了以下两项工作:

  1. 共享内存中 。init.workspace 函数
  2. 利用gcc的Constructor属性指明_libc_prenit函数,libc_prenit函数.libc_ini_common.c文件中->_libc_init_comment->system.propertis_init()//初始化客户端属性存储区域

1.2.2 属性服务器分析
(1)start_property_service函数,该函数在Property_service.c文件中,该文件与init.c文件中同一个目录。
函数如下:

void start_property_service(void)
{
    int fd;
    //  装载不同的属性文件
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
    load_override_properties();
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
    //  创建socket服务(属性服务)
    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
    if(fd < 0) return;
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    fcntl(fd, F_SETFL, O_NONBLOCK);
    //  开始服务监听
    listen(fd, 8);
    property_set_fd = fd;
}

在start_property_service 中执行了:load_persistent_properties();
// 创建socket服务(属性服务)。客户端只通过对此进行属性设置。
并定义两个宏(和系统预定属性文件路径有关)
将属性文件加载到属性空间中,四个储存属性的文件分别是:

#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"

(2)处理设置请求(在init进程for循环中):
handle_property_set_fd进行处理。权限满足,调用property_set进行处理。
(3)客户端发送请求。
property_set 发送请求,由libcutils库进行提供。propertis.c文件中。

Android系统启动流程(一)解析init进程启动过程 作为“Android框架层”这个大系列中的第一个系列,我们首先要了解的是Android系统启动流程,在这个流程中会涉及到很多重要的知识点,这个系列我们就来一一讲解它们,这一篇我们就来学习init进程。 阅读详情

相关推荐

Android系统启动(一)— init 进程启动过程

Android和Android系统服务。严格来说,Android系统实际是运行在Linux内核之上的一系列“服务进程”,而这些服务进程的“老祖宗”就是init进程。initAndroidPID1Androidinit.rcAndroidinit.rcinitmkdirmountinit.rcZygoteinitLinuxinit.rcinitAndroid 10对init进程的入口函数进行了调整,不再是之前的的main函数,**而是换成了的main。

xingyu19911016的博客 4721

init启动进程

init启动进程需要读取()配置文件 1,启动init进程的配置文件是/etc/inittab 2,/etc/sysvinit是系统初始化用的 /sbin/init在核心完整的加载后,开始运行系统的第一支程序,主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等。 /bin/sh解释脚本的shell命令,开机后运行 /...

weixin_34151004的博客 562

Android系统启动流程(一)解析init进程启动过程(2)

希望本文对你有所启发,有任何面试上的建议也欢迎留言分享给大家。好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。

lingyued的博客 1242

Init 进程详解

Android 内核加载完成后,就会启动init进程,init进程是Android系统用户空间的第一个进程。init程序放在系统根目录下,init进程代码位于源码的目录“system/core/init”下面。下面我们来分析init进程的启动过程1. 分析入口函数进程init入口函数是main,具体实现文件的路径是: system\core\init\init.c 分析main函数:int ma

七月冷雨 1万+

Android6.0系统启动流程分析一:init进程

到了Android6.0,Init进程使用c++来写了,不过没有关系,它和c写的init没有太大的区别。 Init进程的入口代码是:system\core\init\init.cpp main函数: int main(int argc, char** argv) { if (!strcmp(basename(argv[0]), "ueventd")) { return u

阳光玻璃杯 4376

老N卡福音:GT1030/GTX1050在MacOS Ventura 13.2上的完整驱动指南(附实测截图)

本文详细介绍了如何在MacOS Ventura 13.2上通过OCLP工具链驱动GT1030和GTX1050等老款NVIDIA显卡,涵盖硬件兼容性验证、BIOS设置、OpenCore配置、驱动安装及性能测试全流程。实测数据显示,这些基于Pascal和Maxwell架构的显卡在当代MacOS系统中仍能发挥实用价值,为老N卡用户提供完整解决方案。

weixin_30832143的博客 632

init进程

init进程 – 干了啥事 基于aosp/android11-release kernel启动init the kernel boots core kernel initialization memory and I/O areas are initialized interrupts are started, and the process table is initialized driver initialization kernel daemons (threads) are starte

许浑的博客 1311

近4000张真实城市场景行人数据集:YOLO训练实战指南

行人检测是计算机视觉在智能驾驶与机器人感知中的基础任务,其核心挑战在于模型对真实道路场景的鲁棒性——尤其在小目标、遮挡、光照变化及中国特有交通参与者(如外卖骑手、接娃家长)下的泛化能力。本文围绕轻量化、高覆盖、强落地性的近4000张实采图像,系统阐释如何构建面向YOLO系列模型的高质量训练数据集:从四维场景采样策略(光照-遮挡-尺度-姿态)出发,解析标注规范对检测精度的关键影响,并说明数据增强需服务于真实干扰源(雨痕、动态模糊、对比度衰减),而非盲目堆叠。该数据集专为已掌握YOLO训练流程的算法工程师、嵌入

weixin_32495691的博客 297

init在c语言,内核初始化:init/mainc之init();

在sched_init();中对进程0进行了初始化,当所有都初始完之后,就打开中断,将进程0移动到应用层,自此进程0开始执行。接着if (!fork()),创建进程1,并在进程1里执行init();下面看下init代码:void init(void){int pid,i;setup((void *) &drive_info);/******************************...

weixin_34378978的博客 2069

kaggle-NeurIPS - Open Polymer Prediction 2025-0.069

本文摘要: 本研究基于多任务学习框架,开发了聚合物物理化学性质预测模型,能够根据SMILES字符串同步预测玻璃化转变温度(Tg)、分数游离体积(FFV)等5种关键性质。针对数据缺失率高、样本不均衡等挑战,采用"先补充后扩充"策略整合多源数据,并融合RDKit分子描述符、ChemBERTa语义特征和自编码器特征构建多维度表征。模型采用硬参数共享架构,结合动态加权损失函数和早停机制,在验证集上表现出色,其中密度预测R²达0.92。研究为聚合物性能的高通量预测提供了有效解决方案,对材料智能设计具有重要参考价值。

2302_78976920的博客 783

浅谈天线 - - - GNSS/BT/4G/2.4G

全球定位导航系统,最成熟的就是美利坚,我大中华,俄罗斯,还有就是欧洲的一个(太次不谈)所以我们在项目调试的时候,小尺寸的陶瓷天线上一般兼容2个频段,体积大一点的可以兼容三个频段,采用组合的形式 GPS+BD GPS+GLONASS GLONASS+BD 或者是单频段的定位天线陶瓷PATC陶瓷片:陶瓷片面积越大,介电常数越大,其共振频率越高,接收效果越高,这就是为什么都推荐使用大一点的陶瓷天线的原因银层:陶瓷天线表面的银层可以影响天线的共振频率,理想的GNSS陶瓷片频点准确落在1575.42MH

BLACKHOLE6的博客 1万+

Android13 启动流程一,深入探索Init进程的启动奥秘上

在Android系统启动过程中,init进程作为第一个用户空间进程(PID=1) ,承担着初始化系统环境、解析关键配置、启动核心服务等核心职责。\android13-r44\system\core\init\README.md ,里面介绍的还是很详细的。中定义的命令会被添加到“命令执行队列”的尾部(如果命令已经存在,则不会重复添加)。四种声明类型,实现了系统的硬件初始化、服务启动、命令执行等关键功能。文件的语法和功能,对于 Android 系统的开发和调试具有重要意义。启动指定的服务(如果尚未运行)。

qq_33846156的博客 2096

用Python实现古诗词填字游戏(三)

古诗词做填字游戏的第三部分代码,也是最核心的部分。实现对诗文和关键字的选定,并确定文字的输出位置。

PosPro的专栏 6117

Android 系统启动流程(一)从按电源到init进程启动

创建一些文件夹并挂载设备启动selinux安全策略初始化和启动属性服务解析init.rc配置文件并启动zygote进程Android系统启动流程(一)解析init进程启动过程Android 启动过程 - 从上电到init进程的建立安卓启动 Init 进程源码分析从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程面试官:“请描述一下Android系统的启动流程”Android启动流程Android12源码—— init进程。

qq_27494201的博客 1130

从气象预报到物流规划:多尺度地理加权回归(MGWR)在ArcGIS Pro中的实战应用

本文深入探讨了多尺度地理加权回归(MGWR)在ArcGIS Pro中的实战应用。通过对比传统GWR模型,MGWR的核心优势在于能识别不同解释变量的独特空间作用尺度,有效解决空间异质性问题。文章结合气象预报误差修正与物流网点选址两个案例,详细讲解了从数据准备、参数设置、带宽优化到结果解读的全流程,为地理数据分析师处理复杂空间数据提供了强大工具。

egg99的博客 1030

用LTspice仿真CMOS反相器功耗?这份避坑指南能省你3天调试时间

本文详细介绍了如何使用LTspice准确仿真CMOS反相器的功耗,包括动态功耗、短路功耗和静态功耗的测量技巧。通过工程实践指南,帮助电子工程师避开常见陷阱,优化仿真参数设置,提升仿真结果的可靠性,节省调试时间。

w7x8y9z的博客 188

Android13 启动流程一,深入探索Init进程的启动奥秘下

Android13 启动流程一,深入探索Init进程的启动奥秘下。

qq_33846156的博客 915

垂直领域论坛数据挖掘:Python突破Discuz!加密与用户画像构建指南

在垂直领域论坛,如专业技术论坛、兴趣爱好社区等,积累了大量有价值的信息和用户数据。这些数据不仅可以帮助我们了解用户的行为模式和兴趣点,还能为社区运营、产品优化、商业决策等提供有力支持。然而,许多基于Discuz!系统的论坛对数据进行了加密保护,给数据挖掘带来了一定的挑战。本文将详细探讨如何使用Python突破Discuz!论坛的加密机制,并构建用户画像,实现数据掘金。

u014481728的博客 1693

Android系统启动流程(一) init进程启动过程解析

init进程是Android系统第一个用户态的进程,init被赋予了很多重要的职责,比如我们熟悉的Zygote孵化器进程就是由init进程启动的。今天我们就来学习init进程的启动过程。 1 init进程启动之前分析 在分析init进程之前,我们先简单说一下init之前的步骤,大概流程如下: 1) 按Power键启动电源及系统启动 当按下电源键,引导芯片代码开始从固化在ROM中预定义的地方开始执行,加载引导程序Bootloader到RAM,然后执行引导程序。 2) 引导程序Bootloader 引导程序.

周将的博客 3498

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android 系统启动流程(一) init进程启动过程

1. 概述 init进程是Linux系统中用户空间的第一个进程。由于Android是基于Linux内核的,所以init进程也是Android系统中用户空间的第一个进程,它的进程号是1,作为天字一号进程,它被赋予很多重要的职责,但本次我们就关注它的2个重要职责:init进程如何创建zygote进程、init进程如何初始化并启动属性服务。 2. init启动之前的工作 当按下Power键,引导芯片加载...

Kelly_ge的博客 1478

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

[Android的Init进程一]启动脚本init.rc

Android Init语言由五个大类的语句组成,Actions, Commands, Services, Options, Imports。 1.Actions on <trigger> <command> <command> <command> 2.Commands 3.Services service <name> <pathname> [ <argument> ]* &lt

z9722的博客 286

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

OpenWRT 启动流程(一) /sbin/init 进程分析

小结: 1./sbin/init 怎么来的?来自procd 2. /sbin/init 做了些什么?/sbin/init 进程最终是启动了/sbin/procd 进程,并执行/etc/preinit 脚本

我的学习笔记 5702
上一篇: Window 和windowManager源码分析
下一篇: Kotlin 资料准备与环境搭建
Nela
博客等级 码龄11年 9粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值