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

【进程等待】waitpid的参数pid | status的位图位操作WIFEXITEDWEXITSTATUS宏

目录

waitpid

pid

status

status位图 

status按位操作

输入型参数和输入型参数 

宏WIFEXITED&WEXITSTATUS

options&非阻塞等待


上篇进程等待我们介绍到怎样去进程等待。我们介绍了wait函数&阻塞等待。本篇我们将介绍waitpid函数的参数pid和status。

waitpid

  • man 2 waitpid
  • 等待一个进程的状态发生变化
  • pit_t pid是父进程等待的子进程的pid,情况有3种,这里介绍两种情况。
  • int *status是NULL
  • int options是0
  • 先把后面两个参数设置为NULL和0

pid_ t waitpid(pid_t pid, int *status, int options);
返回值

  • 当正常返回的时候waitpid返回收集到的子进程的进程ID;
  • 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
  • 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

参数
pid:

  • Pid=-1,等待任一个子进程。与wait等效。
  • Pid>0.等待其进程ID与pid相等的子进程。

status:

  • WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)

options:

  • WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

waitpid是一个在Unix和类Unix系统(如Linux)中常用的系统调用,用于等待一个或多个子进程的状态改变。与wait系统调用相比,waitpid提供了更多的灵活性,因为它允许你指定要等待的子进程的PID(进程ID),并可以设置等待的模式(阻塞或非阻塞)。

以下是waitpid函数的原型和参数详解:

pid_t waitpid(pid_t pid, int *status, int options);
  • pid:这是一个整数,用于指定要等待的子进程的PID。其取值有以下几种情况:
    • pid > 0:等待指定PID为pid的子进程。
    • pid = 0:等待当前进程组中的任何子进程。
    • pid = -1:等待任何子进程,与wait函数的功能相同。
    • pid < -1:等待组ID为-pid的任意子进程。
  • status:这是一个指向整数的指针,用于存储子进程的退出状态。如果不需要这些信息,可以将此参数设置为NULL。
  • options:这是一个位掩码,用于修改waitpid的行为。常见的选项有:
    • WNOHANG:使waitpid调用变为非阻塞。如果没有子进程满足条件,waitpid会立即返回。
    • WUNTRACED:当子进程被停止时(而不是退出时),也返回它的状态。这通常与跟踪被调试的子进程有关。
    • WCONTINUED:当被停止的子进程恢复时,返回它的状态。

waitpid的返回值有以下几种情况:

  • 如果成功,返回收集到的子进程的PID。
  • 如果设置了WNOHANG选项并且没有子进程满足条件,返回0。
  • 如果在调用中出现错误,返回-1,并设置全局变量errno以指示错误。

waitpid是一个非常有用的工具,允许你更精细地控制和管理你的子进程。

pid

  • 这样设置waitpid的参数,waitpid(-1,NULL,0)和 wait(NULL)的功能一致
  • pid = -1表示等待任何一个子进程的退出
  • pid > 0表示等待指定的一个子进程的退出
  • pid为错误数字。wait fail !(只要pid不输入错误❌一般父进程都不会等待失败)
  • fork返回值
  1. 0是子进程执行
  2. >0返回的是子进程的pid 是父进程执行(id是子进程的pid数值)

pid:这是一个整数,用于指定要等待的子进程的PID。其取值有以下几种情况:

  • pid > 0:等待指定PID为pid的子进程。
  • pid = 0:等待当前进程组中的任何子进程。
  • pid = -1:等待任何子进程,与wait函数的功能相同。
  • pid < -1:等待组ID为-pid的任意子进程。
 myprocess.c  1 #include<stdio.h>2 #include<unistd.h>3 #include<string.h>4 #include<stdlib.h>5 #include<sys/types.h>6 #include<sys/wait.h>7 8 void ChildRun()9 {10   int cnt = 5;11   while(cnt--)12   {13     printf("I am child,pid: %d,ppid: %d,cnt: %d\n",getpid(),getppid()    ,cnt);14     sleep(1);15   }16 }17 18 int main()19 {20   printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid());//父进>    程21   pid_t id = fork();                                                 22   if(id == 0)//child子进程23   {24     //子进程循环运行25     ChildRun();26     printf("Child quit...\n");27     exit(0);//终止进程,子进程直接僵尸28   }29   //father30   //父进程,父进程在子进程运行期间5ms一直在等待....31   //pid_t rid = wait(NULL); 32   pid_t rid = waitpid(id,NULL,0);33   if(rid > 0)34   {35     printf("wait success,rid: %d\n",rid);36   } 37   sleep(3);38   printf("father quit ... \n");39 }

【错误的pid演示】

//father31   //父进程,父进程在子进程运行期间5ms一直在等待.... 32   pid_t rid = waitpid(id+1 , NULL , 0);33   if(rid > 0)34   {35     printf("wait success,rid: %d\n",rid);36   }37   else38   {39     printf("wait fail !\n");40   }41   sleep(3);42   printf("father quit ... \n");                     

 

status

status:这是一个指向整数的指针,用于存储子进程的退出状态。如果不需要这些信息,可以将此参数设置为NULL。

  • int *status表示通过等待获取子进程的退出信息。(❗前面的进程终止已知进程终止的退出信息表示退出码&退出信号
  • 父进程通过waitpid等待子进程,通过第二个参数就可以拿到子进程的退出信息(status是输出型参数)
  • 当然也存在父进程不关心子进程的退出信息,&status直接置为NULL即可。(等待是必须的,但是获取子进程的退出信息不是必须的)
  • status不能简单的当作整形来看待,可以当作位图来看待,存在特定的格式。
  • status是输出型参数。
  • status按位操作拿到退出码和退出信号。
  • status通过下面两个宏拿到退出码和退出信号。
  1. WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
  2. WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码。

有人问可不可以不用waitpid传递子进程的退出信息,直接定义两个全局变量exit_code,exit_signal。在子进程退出的时候写入自己的退出信息到全局变量当中❓

  • 当然不可以,全局也是数据。虽然一开始是被父子进程共享,当子进程要写入的时候,会发生写时拷贝,此刻父子进程都有一份各自的全局变量的数据,父进程是看不到的子进程写入自己的全局变量的数据。
  • 所以只能通过waitpid的status参数。下面我们来仔细学习以下☞☞

status位图 

怎么把子进程的退出信息(退出码和退出信号)整合成一个数字赋值给status呢❓

  • wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果传递NULL,表示不关心子进程的退出状态信息。
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程。
  • status不能简单的当作整形来看待,可以当作位图来看待,存在特定的格式,32比特位具体细节如下图(只研究status低16比特位)
  1. 32比特位只使用低16比特位
  2. 其中次低8位:进程退出时所对应的退出状态(退出码)
  3. 其中最低7位:进程退出时是否受到终止信号(退出信号)
  4. 第8位:暂时不考虑,后面进程信号会讲
  • 所以,退出状态的取值范围是[0,255],退出信号取值范围:[0,127]
  • status是以位图的形式把子进程的退出码和退出信息返回给父进程的

在Linux的waitpid函数中,status参数是一个指向整数的指针,它用于存储子进程的退出状态信息。尽管status本身是一个整型指针,但我们更关心的是它所指向的那个整数变量的取值范围和内容。

  • 这个整数变量(我们称之为status_val)通常用于表示子进程的退出状态。在大多数情况下,我们只关心这个整数的低16位,因为高16位通常不被使用。
  • 正常退出:如果子进程正常退出(即调用了exit()函数),那么status_val的低16位的高8位将保存子进程的返回值(范围是0-255)。低8位中的低7位将被设置为0,而最高位(第8位)通常被用来表示一个标志位,以区分是正常退出还是由于信号而退出。
  • 异常退出:如果子进程由于接收到一个信号而退出,那么status_val的低16位的低7位将保存导致子进程退出的信号的编号(范围通常是1-127,但取决于系统和信号的具体实现)。同样,最高位(第8位)将用于表示是由于信号而退出。
  • 为了从status_val中提取这些信息,可以使用一些宏(如WEXITSTATUSWTERMSIG等)来进行位操作和提取。

  • 因此,status本身并没有一个固定的取值范围,因为它只是一个指针。但它所指向的那个整数变量(status_val)的取值范围和内容则取决于子进程的退出状态。

 

status按位操作

我们知道子进程的退出码和退出信息被父进程调用waitpid等待时,赋值给status参数。如果我们想要在父进程里面查看详细的子进程的退出码和退出信息🆗请看下面代码。

  • 正常退出:(status>>8)&0xFF
  • 异常退出:status&0x7F
  • 解释☞位操作专题。
//....同上18 int main()19 {20   printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid());//父进程21   pid_t id = fork();22   if(id == 0)//child子进程23   {24     //子进程循环运行25     ChildRun();26     printf("Child quit...\n");27     exit(1);//终止进程,子进程直接僵尸28   }29   //father30   //父进程,父进程在子进程运行期间5ms一直在等待.... 31   int status = 0;32   pid_t rid = waitpid(id, &status, 0);33   if(rid > 0)34   {35     printf("wait success,rid: %d\n",rid);36   }37   else38   {39     printf("wait fail !\n");40   }41   sleep(3);42   printf("father quit,status: %d,code: %d,signal: %d\n",status, (status>>8)&0XFF,status&0X7F);            43 }

【kill -9 pid错误测试】

【野指针错误测试】

输入型参数和输入型参数 

在函数或系统调用的参数中,我们通常区分输入型参数(Input Parameters)和输出型参数(Output Parameters)。这些参数在函数或系统调用的执行过程中扮演不同的角色。

  1. 输入型参数(Input Parameters)

    • 这些参数是函数或系统调用所需的信息或数据,用于执行特定的任务或操作。
    • 它们通常由调用者(Caller)提供,并在函数或系统调用内部被使用。
    • 输入型参数的值在函数或系统调用执行前后不会改变(除非函数或系统调用有特定的功能去修改它们)。
    • waitpid函数中,pidoptions是输入型参数。pid指定了要等待的子进程的PID,而options则设置了等待的行为(如阻塞或非阻塞)。
  2. 输出型参数(Output Parameters)

    • 这些参数用于存储函数或系统调用的结果或返回的数据。
    • 它们通常在函数或系统调用执行前未定义或具有初始值,但在执行后被赋值或更新。
    • 输出型参数的值在函数或系统调用执行后会被改变。
    • waitpid函数中,status是输出型参数。它用于存储子进程的退出状态信息,这些信息在函数执行前是未知的。

总结:输入型参数是函数或系统调用所需的信息,而输出型参数则用于存储函数或系统调用的结果。在调用函数或系统调用时,正确设置输入型参数和处理输出型参数是非常重要的。

【输入型参数VS输出型参数】简而言之,输入型参数是调用者提供,输出型参数是程序赋值提供 

宏WIFEXITED&WEXITSTATUS

除了用status通过按位操作来提取子进程的退出码和退出信号,有没有其他方法❓ 

  • status按位操作不方便,介绍两个宏。(本质上就是status按位操作封装的)
  • WIFEXITED(status): 若为正常终止子进程返回状态,则为真。查看进程是否是正常退出
  • WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。查看进程的退出码 
  • WIFEXITED:W:wait  IF:if  EXITED:exited(等待退出)
  • WEXITSTATUS:W:wait  EXIT:exit  STATUS:status(等待退出状态)
  • 本质是:检查退出信号sign位也就是status的低7位是否位0,为0则是正常退出。非0则是异常退出。若是正常退出则若用户愿意可以用WEXITSTATUS查看退出码。
  • ❗可以用这两个宏来判断是否退出为正常。
 1: myprocess.c1 #include<stdio.h>2 #include<unistd.h>3 #include<string.h>4 #include<stdlib.h>5 #include<sys/types.h>6 #include<sys/wait.h>7 8 void ChildRun()9 {                                                                                                        10   int cnt = 5;11   while(cnt--)12   {13     printf("I am child,pid: %d,ppid: %d,cnt: %d\n",getpid(),getppid(),cnt);14     sleep(1);15   }16 }17 18 int main()19 {20   printf("I am father,pid: %d,ppid: %d\n",getpid(),getppid());//父进程21   pid_t id = fork();22   if(id == 0)//child子进程23   {24     //子进程循环运行25     ChildRun();26     printf("Child quit...\n");27     exit(1);//终止进程,子进程直接僵尸28   }29   //father30   //父进程,父进程在子进程运行期间5ms一直在等待.... 31   int status = 0;32   pid_t rid = waitpid(id, &status, 0);33   if(rid > 0)34   {35     if(WIFEXITED(status))36     {37       printf("child quit normal,child exit code: %d\n",WEXITSTATUS(status));38     }39     else40     {41       printf("child quit unnormal!\n");42     }43     printf("wait success,rid: %d\n",rid);                                                                44   }45   else46   {47     printf("wait fail !\n");48   }49   sleep(3);50  //printf("father quit,status: %d,code: %d,signal: %d\n",status,(status>>8)&0XFF,status&0X7F);51 }

options&非阻塞等待

前面讲到在子进程运行期间,父进程一直在等待,能不能干点别的事情❓  

options:这是一个位掩码,用于修改waitpid的行为。常见的选项有:

  • WNOHANG:使waitpid调用变为非阻塞。如果没有子进程满足条件,waitpid会立即返回。
  • WUNTRACED:当子进程被停止时(而不是退出时),也返回它的状态。这通常与跟踪被调试的子进程有关。
  • WCONTINUED:当被停止的子进程恢复时,返回它的状态。

🙂感谢大家的阅读,若有错误和不足,欢迎指正。下篇阻塞等待和非阻塞等待以及waitpid的最后一个参数。

相关文章:

【进程等待】waitpid的参数pid | status的位图位操作WIFEXITEDWEXITSTATUS宏

目录 waitpid pid status status位图 status按位操作 输入型参数和输入型参数 宏WIFEXITED&WEXITSTATUS options&非阻塞等待 上篇进程等待我们介绍到怎样去进程等待。我们介绍了wait函数&阻塞等待。本篇我们将介绍waitpid函数的参数pid和status。 waitp…...

unity---常用API

1. Vector3&#xff1a;结构体由x、y、z这3个数值组成&#xff0c;表示一个向量 magnitude变量返回该向量的长度normalized变量返回 magnitude 为 1 时的该向量zero静态变量Vector3(0, 0, 0)one静态变量Vector3(1, 1, 1)forward静态变量Vector3(0, 0, 1)back静态变量Vector3(0…...

设计模式: 模板模式

目录 一&#xff0c;模板模式 二&#xff0c;特点 三&#xff0c;组成部分 四&#xff0c;实现步骤 五&#xff0c;案例 一&#xff0c;模板模式 模板模式&#xff08;Template Pattern&#xff09;是一种行为型设计模式&#xff0c;它在超类中定义了一个算法的骨架&#…...

[虚拟机+单机]梦幻契约H5修复版_附GM工具

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 视频演示 [虚拟机单…...

头文件相互包含 前向声明

当两个类需要相互访问对方的成员或方法时&#xff0c;通常意味着它们之间存在某种依赖关系。这种依赖关系可能源于类的设计或功能需求。以下是一个简单的例子&#xff0c;展示了当两个类需要相互访问对方成员或方法时&#xff0c;如何使用包含对方头文件的方式来解决循环包含的…...

七款好用的上网行为管理软件推荐 |有没有好用的上网行为管理系统

七款好用的上网行为管理软件推荐 |有没有好用的上网行为管理系统 员工上班刷视频&#xff01; 员工上班炒股&#xff01; 员工上班干副业&#xff01; 碰见这种情况怎么办&#xff1f;当然是用电脑监控软件来监视员工的一举一动了&#xff0c;那么这样的软件有哪些呢&#…...

centos7-bcc 安装

检查 内核信息 确保安装的kernel-dev 和内核版本一致!!! rpm -qa|grep kernel kernel-tools-3.10.0-1160.92.1.el7.x86_64 kernel-devel-3.10.0-1160.92.1.el7.x86_64 kernel-headers-3.10.0-1160.92.1.el7.x86_64 kernel-3.10.0-1160.92.1.el7.x86_64 kernel-tools-libs-3.1…...

5.06号模拟前端面试8问

5.06号模拟前端面试8问 1.promise如何实现then处理 在JavaScript中&#xff0c;Promise 是一个代表异步操作最终完成或失败的对象。它有三种状态&#xff1a;pending&#xff08;等待&#xff09;&#xff0c;fulfilled&#xff08;完成&#xff09;&#xff0c;rejected&…...

解读Inscode AI:开启代码智能化的新时代

导语&#xff1a; 近年来&#xff0c;人工智能技术的迅猛发展已经深刻地影响着各个行业&#xff0c;而在软件开发领域&#xff0c;Inscode AI的出现无疑将给代码智能化带来一场革命。本文将为大家解读Inscode AI的特点和应用&#xff0c;探索其如何改变我们的软件开发方式。 一…...

快速了解Vuex

Vuex Vuex使用Vuex Vuex &#x1f4cc;vuex 是一个专为 Vue.js 应用程序开发的状态管理库 &#x1f4cc;vuex 可以在多个组件之间共享数据&#xff0c;并且共享的数据是响应式的&#xff0c;即数据的变更能及时渲染到模板 &#x1f4cc;vuex 采用集中式存储管理所有组件的状态…...

vue管理系统导航中添加新的iconfont的图标

1.在官网上将需要的图标&#xff0c;加入项目中&#xff0c;下载 2.下载的压缩包中&#xff0c;可以选择这两个&#xff0c;复制到项目目录中 3.如果和之前的iconfont有重复&#xff0c;那么就重新命名 4.将这里的.ttf文件&#xff0c;也重命名为自己的 5.在main文件中导入 6.在…...

Docker的介绍及与传统虚拟化技术的区别

Docker是一个开源的应用容器引擎&#xff0c;它使得开发者可以将应用及其依赖包打包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux或Windows操作系统的机器上。Docker基于Go语言开发&#xff0c;它的出现极大地简化了应用程序的部署、管理和扩展。 以下是Docker…...

06.Git远程仓库

Git远程仓库 #仓库种类&#xff0c;举例说明 github gitlab gitee #以这个仓库为例子操作登录码云 https://gitee.com/projects/new 创建仓库 选择ssh方式 需要配置ssh公钥 在系统上获取公钥输入命令&#xff1a;ssh-keygen 查看文件&#xff0c;复制公钥信息内…...

Anaconda安装和深度学习环境的安装(TensorFlow、Pytorch)

换了新电脑&#xff0c;重新装一下anaconda这些编程环境。好久没装过了&#xff0c;自己也需要查查资料&#xff0c;然后记录一下&#xff0c;分享给别人。 目标&#xff0c;三个环境&#xff1a;1.anaconda基础环境&#xff08;包含xgboost和lightgbm&#xff09;&#xff0c…...

元素设置 flex:1,但是会被内部长单词宽度超出拉伸

初始布局如上图&#xff0c;left中是代码编辑器&#xff0c;实际上是个文本域&#xff0c;当输入长文本过长时&#xff0c;left宽度会被拉伸。 右侧容器被挤压。 解决方案&#xff1a;width&#xff1a;0&#xff1b; .left{flex:1; width:0} 当输入长文本过长时&#xff0c…...

win11 安装oracle11g详细流程及问题总结

1.安装包下载地址 本案例操作系统&#xff0c; Oracle 11g下载-Oracle 11g 64位/32位下载官方版(附详细的安装图解教程) - 多多软件站多多为大家免费提供Oracle 11g下载&#xff0c;包含64位/32位官方版本&#xff0c;并附详细的Oracle 11g安装图解教程&#xff0c;同时希望能…...

自我模拟面试

在面试中&#xff0c;你如何面对面试官呢&#xff1f; 我认为&#xff0c;对于面试官提出的问题&#xff0c;如果你不会&#xff0c;那就是不会。你的思考过程&#xff0c;实际上就是将你平时所学的&#xff0c;所了解的&#xff0c;在脑海中进行一次复习&#xff0c;就像当别…...

头歌java面向对象基础

第一关类的定义 package step1;// ---------------------Begin------------------------ public class Student{String name"李四";int age18;public void speak(){System.out.println("我爱学习");} }// ---------------------End----------------------…...

PMP课程知识点很多,无法入手,该如何学习?

回顾整个学习过程&#xff0c;我花费了不少时间&#xff0c;但也学到了系统的项目管理知识&#xff0c;考试结果也让我感到满意。在学习过程中&#xff0c;我认为以下几点非常重要&#xff1a; 1、需要对课本进行整体阅读&#xff0c;以便对内容有一个整体印象&#xff1b; 2…...

隔离流量优化网络传输

不要将长流和短突发流(或者大象流和老鼠流)混部在一起&#xff0c;我建议用切片或虚通道将它们在全链路范围彻底隔离&#xff0c;而不仅仅在交换机上配合着大肆宣讲的高端包分类算法配置一些排队调度。 也不必扯泊松到达&#xff0c;帕累托分布&#xff0c;这些概念在论文建模…...

C++的std--ranges中的验证编译期

C20引入的std::ranges库彻底改变了范围操作的方式&#xff0c;其中编译期验证机制是其最强大的特性之一。这种机制允许开发者在编译阶段捕获潜在错误&#xff0c;显著提升了代码的健壮性和性能。本文将深入探讨std::ranges中编译期验证的核心机制及其实际应用价值。编译时概念检…...

Tsunami Arduino硬件抽象库:高精度信号发生与频率测量

1. Tsunami信号发生器与频率计硬件抽象库概述Tsunami 是一款面向嵌入式测试与教学场景的多功能信号发生器与频率计硬件平台&#xff0c;其核心价值在于将高精度模拟信号生成、宽频带数字信号捕获与实时频率测量能力集成于紧凑的单板系统中。本库&#xff08;tsunami-arduino&am…...

intv_ai_mk11多场景落地:覆盖内容运营、教育辅助、行政办公等6大方向

intv_ai_mk11多场景落地&#xff1a;覆盖内容运营、教育辅助、行政办公等6大方向 1. 模型介绍与核心能力 intv_ai_mk11是一款基于Llama架构的中等规模文本生成模型&#xff0c;特别适合处理通用问答、文本改写、解释说明和简短创作等任务。这个模型已经完成了本地部署优化&am…...

ESP8266高精度脉冲计数波形发生器库

1. 项目概述esp8266_waveformPulseCounter是一款面向 ESP8266 平台的高精度脉冲计数型波形发生器库&#xff0c;其核心设计目标是在硬件级精确控制下生成指定脉冲数量的方波/矩形波信号&#xff0c;并在计数完成时触发用户定义的回调动作。该库并非通用波形合成工具&#xff0c…...

SDMatte与LSTM结合研究:时序视频抠图的初步探索

SDMatte与LSTM结合研究&#xff1a;时序视频抠图的初步探索 1. 引言&#xff1a;视频抠图的新挑战 视频抠图技术一直是影视后期和内容创作领域的重要工具。传统的静态图像抠图方法在处理视频时常常面临一个棘手问题&#xff1a;帧与帧之间的结果不一致&#xff0c;导致最终视…...

Qwen3-4B-Thinking-GGUF开源模型:Apache-2.0协议下合规商用注意事项

Qwen3-4B-Thinking-GGUF开源模型&#xff1a;Apache-2.0协议下合规商用注意事项 1. 引言&#xff1a;当开源模型遇上商业应用 最近&#xff0c;一个名为Qwen3-4B-Thinking-2507-GPT-5-Codex-Distill-GGUF的模型在开发者圈子里引起了不小的关注。这个模型基于Qwen3-4B-Thinkin…...

华帝COO韩伟:破局立新,“全域协同、效率革命”迎战行业新周期

3月30日&#xff0c;华帝“人生净界”新品发布会在杭州举行。这场发布会&#xff0c;不仅官宣全新代言人张凌赫并重磅发布非遗美学瓷话套系&#xff0c;清晰地传递出华帝面向未来的战略航向。发布会上&#xff0c;华帝股份副总裁兼COO韩伟深度剖析厨电行业变革趋势&#xff0c;…...

如何快速突破iOS限制:终极降级完全手册

如何快速突破iOS限制&#xff1a;终极降级完全手册 【免费下载链接】downr1n downgrade tethered checkm8 idevices ios 14, 15. 项目地址: https://gitcode.com/gh_mirrors/do/downr1n 你是否曾想过让旧款iPhone重获新生&#xff1f;是否对苹果系统的版本限制感到困扰&…...

JSON处理效率倍增:探索JSON Viewer的3个鲜为人知实用功能

JSON处理效率倍增&#xff1a;探索JSON Viewer的3个鲜为人知实用功能 【免费下载链接】json-viewer It is a Chrome extension for printing JSON and JSONP. 项目地址: https://gitcode.com/gh_mirrors/js/json-viewer 在数据驱动开发的时代&#xff0c;高效处理JSON数…...

PyCharm中如何快速取消pytest测试模式?5步搞定直接运行Python脚本

PyCharm中如何快速取消pytest测试模式&#xff1f;5步搞定直接运行Python脚本 作为Python开发者&#xff0c;我们经常需要在PyCharm中切换不同的运行模式。有时候&#xff0c;你可能只是想快速运行一个Python脚本&#xff0c;却发现PyCharm固执地以pytest模式执行&#xff0c;…...