专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

深入理解Linux中进程控制(精讲)

  一、进程创建fork函数初识
  在Linux中,fork函数是非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。
  返回值:
  在子进程中返回0,父进程中返回子进程的PID,子进程创建失败返回1。
  进程调用fork,当控制转移到内核中的fork代码后,内核做:分配新的内存块和内核数据结构给子进程。将父进程部分数据结构内容拷贝至子进程。添加子进程到系统进程列表当中。fork返回,开始调度器调度。
  fork之后,父子进程代码共享。例如:
  运行结果如下:
  这里可以看到,Before只输出了一次,而After输出了两次。其中,Before是由父进程打印的,而调用fork函数之后打印的两个After,则分别由父进程和子进程两个进程执行。也就是说,fork之前父进程独立执行,而fork之后父子两个执行流分别执行。
  注意:fork之后,父进程和子进程谁先执行完全由调度器决定。fork函数返回值
  fork函数为什么要给子进程返回0,给父进程返回子进程的PID?
  一个父进程可以创建多个子进程,而一个子进程只能有一个父进程。因此,对于子进程来说,父进程是不需要被标识的;而对于父进程来说,子进程是需要被标识的,因为父进程创建子进程的目的是让其执行任务的,父进程只有知道了子进程的PID才能很好的对该子进程指派任务。
  为什么fork函数有两个返回值?
  父进程调用fork函数后,为了创建子进程,fork函数内部将会进行一系列操作,包括创建子进程的进程控制块、创建子进程的进程地址空间、创建子进程对应的页表等等。子进程创建完毕后,操作系统还需要将子进程的进程控制块添加到系统进程列表当中,此时子进程便创建完毕了。
  也就是说,在fork函数内部执行return语句之前,子进程就已经创建完毕了,那么之后的return语句不仅父进程需要执行,子进程也同样需要执行,这就是fork函数有两个返回值的原因。写时拷贝
  当子进程刚刚被创建时,子进程和父进程的数据和代码是共享的,即父子进程的代码和数据通过页表映射到物理内存的同一块空间。只有当父进程或子进程需要修改数据时,才将父进程的数据在内存当中拷贝一份,然后再进行修改。
  这种在需要进行数据修改时再进行拷贝的技术,称为写时拷贝技术。
  1、为什么数据要进行写时拷贝?
  进程具有独立性。多进程运行,需要独享各种资源,多进程运行期间互不干扰,不能让子进程的修改影响到父进程。
  2、为什么不在创建子进程的时候就进行数据的拷贝?
  子进程不一定会使用父进程的所有数据,并且在子进程不对数据进行写入的情况下,没有必要对数据进行拷贝,我们应该按需分配,在需要修改数据的时候再分配(延时分配),这样可以高效的使用内存空间。
  3、代码会不会进行写时拷贝?
  90的情况下是不会的,但这并不代表代码不能进行写时拷贝,例如在进行进程替换的时候,则需要进行代码的写时拷贝。
  相关视频推荐
  Linux内核进程状态详解
  linux内核,进程调度器的实现,完全公平调度器CFS
  5个方面分析linux内核架构(进程管理,内存管理,网络协议栈。。)
  需要CCLinux服务器架构师学习资料加qun812855908获取(资料包括CC,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCPIP,协程,DPDK,ffmpeg等),免费分享
  fork常规用法一个进程希望复制自己,使子进程同时执行不同的代码段。例如父进程等待客户端请求,生成子进程来处理请求。一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。fork调用失败的原因
  fork函数创建子进程也可能会失败,有以下两种情况:系统中有太多的进程,内存空间不足,子进程创建失败。实际用户的进程数超过了限制,子进程创建失败。二、进程终止进程退出场景
  进程退出只有三种情况:代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。进程退出码
  我们都知道main函数是代码的入口,但实际上main函数只是用户级别代码的入口,main函数也是被其他函数调用的,例如在VS2013当中main函数就是被一个名为tmainCRTStartup的函数所调用,而tmainCRTStartup函数又是通过加载器被操作系统所调用的,也就是说main函数是间接性被操作系统所调用的。
  既然main函数是间接性被操作系统所调用的,那么当main函数调用结束后就应该给操作系统返回相应的退出信息,而这个所谓的退出信息就是以退出码的形式作为main函数的返回值返回,我们一般以0表示代码成功执行完毕,以非0表示代码执行过程中出现错误,这就是为什么我们都在main函数的最后返回0的原因。
  当我们的代码运行起来就变成了进程,当进程结束后main函数的返回值实际上就是该进程的进程退出码,我们可以使用echo?命令查看最近一次进程退出的退出码信息。
  例如,对于下面这个简单的代码:
  代码运行结束后,我们可以查看该进程的进程退出码。〔clVM015centosprocTermination〕echo?
  这时便可以确定main函数是顺利执行完毕了。
  为什么以0表示代码执行成功,以非0表示代码执行错误?
  因为代码执行成功只有一种情况,成功了就是成功了,而代码执行错误却有多种原因,例如内存空间不足、非法访问以及栈溢出等等,我们就可以用这些非0的数字分别表示代码执行错误的原因。
  C语言当中的strerror函数可以通过错误码,获取该错误码在C语言当中对应的错误信息:
  运行代码后我们就可以看到各个错误码所对应的错误信息:
  实际上Linux中的ls、pwd等命令都是可执行程序,使用这些命令后我们也可以查看其对应的退出码。
  可以看到,这些命令成功执行后,其退出码也是0。
  但是命令执行错误后,其退出码就是非0的数字,该数字具体代表某一错误信息。
  注意:退出码都有对应的字符串含义,帮助用户确认执行失败的原因,而这些退出码具体代表什么含义是人为规定的,不同环境下相同的退出码的字符串含义可能不同。进程正常退出return退出
  在main函数中使用return退出进程是我们常用的方法。
  例如,在main函数最后使用return退出进程。
  运行结果:
  exit函数
  使用exit函数退出进程也是我们常用的方法,exit函数可以在代码中的任何地方退出进程,并且exit函数在退出进程前会做一系列工作:执行用户通过atexit或onexit定义的清理函数。关闭所有打开的流,所有的缓存数据均被写入。调用exit函数终止进程。
  例如,以下代码中exit终止进程前会将缓冲区当中的数据输出。
  运行结果:
  exit函数
  使用exit函数退出进程的方法我们并不经常使用,exit函数也可以在代码中的任何地方退出进程,但是exit函数会直接终止进程,并不会在退出进程前会做任何收尾工作。
  例如,以下代码中使用exit终止进程,则缓冲区当中的数据将不会被输出。
  运行结果:
  return、exit和exit之间的区别与联系
  return、exit和exit之间的区别
  只有在main函数当中的return才能起到退出进程的作用,子函数当中return不能退出进程,而exit函数和exit函数在代码中的任何地方使用都可以起到退出进程的作用。
  使用exit函数退出进程前,exit函数会执行用户定义的清理函数、冲刷缓冲,关闭流等操作,然后再终止进程,而exit函数会直接终止进程,不会做任何收尾工作。
  return、exit和exit之间的联系
  执行returnnum等同于执行exit(num),因为调用main函数运行结束后,会将main函数的返回值当做exit的参数来调用exit函数。
  使用exit函数退出进程前,exit函数会先执行用户定义的清理函数、冲刷缓冲,关闭流等操作,然后再调用exit函数终止进程。进程异常退出
  情况一:向进程发生信号导致进程异常退出。
  例如,在进程运行过程中向进程发生kill9信号使得进程异常退出,或是使用CtrlC使得进程异常退出等。
  情况二:代码错误导致进程运行时异常退出。
  例如,代码当中存在野指针问题使得进程运行时异常退出,或是出现除0的情况使得进程运行时异常退出等。三、进程等待进程等待的必要性子进程退出,父进程如果不读取子进程的退出信息,子进程就会变成僵尸进程,进而造成内存泄漏。进程一旦变成僵尸进程,那么就算是kill9命令也无法将其杀死,因为谁也无法杀死一个已经死去的进程。对于一个进程来说,最关心自己的就是其父进程,因为父进程需要知道自己派给子进程的任务完成的如何。父进程需要通过进程等待的方式,回收子进程资源,获取子进程的退出信息。获取子进程status
  下面进程等待所使用的两个函数wait和waitpid,都有一个status参数,该参数是一个输出型参数,由操作系统进行填充。
  如果对status参数传入NULL,表示不关心子进程的退出状态信息。否则,操作系统会通过该参数,将子进程的退出信息反馈给父进程。
  status是一个整型变量,但status不能简单的当作整型来看待,status的不同比特位所代表的信息不同,具体细节如下(只研究status低16比特位):
  在status的低16比特位当中,高8位表示进程的退出状态,即退出码。进程若是被信号所杀,则低7位表示终止信号,而第8位比特位是coredump标志。
  我们通过一系列位操作,就可以根据status得到进程的退出码和退出信号。exitCode(status8)0xFF;退出码exitSignalstatus0x7F;退出信号
  对于此,系统当中提供了两个宏来获取退出码和退出信号。WIFEXITED(status):用于查看进程是否是正常退出,本质是检查是否收到信号。WEXITSTATUS(status):用于获取进程的退出码。exitNormalWIFEXITED(status);是否正常退出exitCodeWEXITSTATUS(status);获取退出码
  需要注意的是,当一个进程非正常退出时,说明该进程是被信号所杀,那么该进程的退出码也就没有意义了。进程等待的方法wait方法
  函数原型:pidtwait(intstatus);
  作用:等待任意子进程。
  返回值:等待成功返回被等待进程的pid,等待失败返回1。
  参数:输出型参数,获取子进程的退出状态,不关心可设置为NULL。
  例如,创建子进程后,父进程可使用wait函数一直等待子进程,直到子进程退出后读取子进程的退出信息。includestdio。hincludestdlib。hincludeunistd。hincludesyswait。hincludesystypes。hintmain(){pidtidfork();if(id0){childintcount10;while(count){printf(Iamchild。。。PID:d,PPID:d,getpid(),getppid());sleep(1);}exit(0);}fatherintstatus0;pidtretwait(status);if(ret0){waitsuccessprintf(waitchildsuccess。。。);if(WIFEXITED(status)){exitnormalprintf(exitcode:d,WEXITSTATUS(status));}}sleep(3);return0;}
  我们可以使用以下监控脚本对进程进行实时监控:〔clVM015centosprocWait〕while:;dopsaxjhead1psaxjgrepprocgrepvgrep;echo;sleep1;done
  这时我们可以看到,当子进程退出后,父进程读取了子进程的退出信息,子进程也就不会变成僵尸进程了。
  waitpid方法
  函数原型:pidtwaitpid(pidtpid,intstatus,intoptions);
  作用:等待指定子进程或任意子进程。
  返回值:
  1、等待成功返回被等待进程的pid。
  2、如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0。
  3、如果调用中出错,则返回1,这时errno会被设置成相应的值以指示错误所在。
  参数:
  1、pid:待等待子进程的pid,若设置为1,则等待任意子进程。
  2、status:输出型参数,获取子进程的退出状态,不关心可设置为NULL。
  3、options:当设置为WNOHANG时,若等待的子进程没有结束,则waitpid函数直接返回0,不予以等待。若正常结束,则返回该子进程的pid。
  例如,创建子进程后,父进程可使用waitpid函数一直等待子进程(此时将waitpid的第三个参数设置为0),直到子进程退出后读取子进程的退出信息。includestdio。hincludestdlib。hincludeunistd。hincludesyswait。hincludesystypes。hintmain(){pidtidfork();if(id0){childintcount10;while(count){printf(Iamchild。。。PID:d,PPID:d,getpid(),getppid());sleep(1);}exit(0);}fatherintstatus0;pidtretwaitpid(id,status,0);if(ret0){waitsuccessprintf(waitchildsuccess。。。);if(WIFEXITED(status)){exitnormalprintf(exitcode:d,WEXITSTATUS(status));}else{signalkilledprintf(killedbysiganld,status0x7F);}}sleep(3);return0;}
  在父进程运行过程中,我们可以尝试使用kill9命令将子进程杀死,这时父进程也能等待子进程成功。
  注意:被信号杀死而退出的进程,其退出码将没有意义。多进程创建以及等待的代码模型
  上面演示的都是父进程创建以及等待一个子进程的例子,实际上我们还可以同时创建多个子进程,然后让父进程依次等待子进程退出,这叫做多进程创建以及等待的代码模型。
  例如,以下代码中同时创建了10个子进程,同时将子进程的pid放入到ids数组当中,并将这10个子进程退出时的退出码设置为该子进程pid在数组ids中的下标,之后父进程再使用waitpid函数指定等待这10个子进程。includestdio。hincludestdlib。hincludeunistd。hincludesystypes。hincludesyswait。hintmain(){pidtids〔10〕;for(inti0;i10;i){pidtidfork();if(id0){childprintf(childprocesscreatedsuccessfully。。。PID:d,getpid());sleep(3);exit(i);将子进程的退出码设置为该子进程PID在数组ids中的下标}fatherids〔i〕id;}for(inti0;i10;i){intstatus0;pidtretwaitpid(ids〔i〕,status,0);if(ret0){waitchildsuccessprintf(wiatchildsuccess。。PID:d,ids〔i〕);if(WIFEXITED(status)){exitnormalprintf(exitcode:d,WEXITSTATUS(status));}else{signalkilledprintf(killedbysignald,status0x7F);}}}return0;}
  运行代码,这时我们便可以看到父进程同时创建多个子进程,当子进程退出后,父进程再依次读取这些子进程的退出信息。
  基于非阻塞接口的轮询检测方案
  上述所给例子中,当子进程未退出时,父进程都在一直等待子进程退出,在等待期间,父进程不能做任何事情,这种等待叫做阻塞等待。
  实际上我们可以让父进程不要一直等待子进程退出,而是当子进程未退出时父进程可以做一些自己的事情,当子进程退出时再读取子进程的退出信息,即非阻塞等待。
  做法很简单,向waitpid函数的第三个参数potions传入WNOHANG,这样一来,等待的子进程若是没有结束,那么waitpid函数将直接返回0,不予以等待。而等待的子进程若是正常结束,则返回该子进程的pid。
  例如,父进程可以隔一段时间调用一次waitpid函数,若是等待的子进程尚未退出,则父进程可以先去做一些其他事,过一段时间再调用waitpid函数读取子进程的退出信息。includestdio。hincludestdlib。hincludeunistd。hincludesystypes。hincludesyswait。hintmain(){pidtidfork();if(id0){childintcount3;while(count){printf(childdosomething。。。PID:d,PPID:d,getpid(),getppid());sleep(3);}exit(0);}fatherwhile(1){intstatus0;pidtretwaitpid(id,status,WNOHANG);if(ret0){printf(waitchildsuccess。。。);printf(exitcode:d,WEXITSTATUS(status));break;}elseif(ret0){printf(fatherdootherthings。。。);sleep(1);}else{printf(waitpiderror。。。);break;}}return0;}
  运行结果就是,父进程每隔一段时间就去查看子进程是否退出,若未退出,则父进程先去忙自己的事情,过一段时间再来查看,直到子进程退出后读取子进程的退出信息。
  四、进程程序替换替换原理
  用fork创建子进程后,子进程执行的是和父进程相同的程序(但有可能执行不同的代码分支),若想让子进程执行另一个程序,往往需要调用一种exec函数。
  当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,并从新程序的启动例程开始执行。
  当进行进程程序替换时,有没有创建新的进程?
  进程程序替换之后,该进程对应的PCB、进程地址空间以及页表等数据结构都没有发生改变,只是进程在物理内存当中的数据和代码发生了改变,所以并没有创建新的进程,而且进程程序替换前后该进程的pid并没有改变。
  子进程进行进程程序替换后,会影响父进程的代码和数据吗?
  子进程刚被创建时,与父进程共享代码和数据,但当子进程需要进行进程程序替换时,也就意味着子进程需要对其数据和代码进行写入操作,这时便需要将父子进程共享的代码和数据进行写时拷贝,此后父子进程的代码和数据也就分离了,因此子进程进行程序替换后不会影响父进程的代码和数据。替换函数
  替换函数有六种以exec开头的函数,它们统称为exec函数:
  一、intexecl(constcharpath,constchararg,。。。);
  第一个参数是要执行程序的路径,第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾。
  例如,要执行的是ls程序。execl(usrbinls,ls,a,i,l,NULL);
  二、intexeclp(constcharfile,constchararg,。。。);
  第一个参数是要执行程序的名字,第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾。
  例如,要执行的是ls程序。execlp(ls,ls,a,i,l,NULL);
  三、intexecle(constcharpath,constchararg,。。。,charconstenvp〔〕);
  第一个参数是要执行程序的路径,第二个参数是可变参数列表,表示你要如何执行这个程序,并以NULL结尾,第三个参数是你自己设置的环境变量。
  例如,你设置了MYVAL环境变量,在mycmd程序内部就可以使用该环境变量。charmyenvp〔〕{MYVAL2021,NULL};execle(。mycmd,mycmd,NULL,myenvp);
  四、intexecv(constcharpath,charconstargv〔〕);
  第一个参数是要执行程序的路径,第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾。
  例如,要执行的是ls程序。charmyargv〔〕{ls,a,i,l,NULL};execv(usrbinls,myargv);
  五、intexecvp(constcharfile,charconstargv〔〕);
  第一个参数是要执行程序的名字,第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾。
  例如,要执行的是ls程序。charmyargv〔〕{ls,a,i,l,NULL};execvp(ls,myargv);
  六、intexecve(constcharpath,charconstargv〔〕,charconstenvp〔〕);
  第一个参数是要执行程序的路径,第二个参数是一个指针数组,数组当中的内容表示你要如何执行这个程序,数组以NULL结尾,第三个参数是你自己设置的环境变量。
  例如,你设置了MYVAL环境变量,在mycmd程序内部就可以使用该环境变量。charmyargv〔〕{mycmd,NULL};charmyenvp〔〕{MYVAL2021,NULL};execve(。mycmd,myargv,myenvp);函数解释这些函数如果调用成功,则加载指定的程序并从启动代码开始执行,不再返回。如果调用出错,则返回1。
  也就是说,exec系列函数只要返回了,就意味着调用失败。命名理解
  这六个exec系列函数的函数名都以exec开头,其后缀的含义如下:l(list):表示参数采用列表的形式,一一列出。v(vector):表示参数采用数组的形式。p(path):表示能自动搜索环境变量PATH,进行程序查找。e(env):表示可以传入自己设置的环境变量。
  事实上,只有execve才是真正的系统调用,其它五个函数最终都是调用的execve,所以execve在man手册的第2节,而其它五个函数在man手册的第3节,也就是说其他五个函数实际上是对系统调用execve进行了封装,以满足不同用户的不同调用场景的。
  下图为exec系列函数族之间的关系:
  做一个简易的shell
  shell也就是命令行解释器,其运行原理就是:当有命令需要执行时,shell创建子进程,让子进程执行命令,而shell只需等待子进程退出即可。
  其实shell需要执行的逻辑非常简单,其只需循环执行以下步骤:获取命令行。解析命令行。创建子进程。替换子进程。等待子进程退出。
  其中,创建子进程使用fork函数,替换子进程使用exec系列函数,等待子进程使用wait或者waitpid函数。
  于是我们可以很容易实现一个简易的shell,代码如下:includestdio。hincludepwd。hincludestring。hincludeunistd。hincludestdlib。hincludesystypes。hincludesyswait。hdefineLEN1024命令最大长度defineNUM32命令拆分后的最大个数intmain(){charcmd〔LEN〕;存储命令charmyargv〔NUM〕;存储命令拆分后的结果charhostname〔32〕;主机名charpwd〔128〕;当前目录while(1){获取命令提示信息structpasswdpassgetpwuid(getuid());gethostname(hostname,sizeof(hostname)1);getcwd(pwd,sizeof(pwd)1);intlenstrlen(pwd);charppwdlen1;while(p!){p;}p;打印命令提示信息printf(〔sss〕,passpwname,hostname,p);读取命令fgets(cmd,LEN,stdin);cmd〔strlen(cmd)1〕;拆分命令myargv〔0〕strtok(cmd,);inti1;while(myargv〔i〕strtok(NULL,)){i;}pidtidfork();创建子进程执行命令if(id0){childexecvp(myargv〔0〕,myargv);child进行程序替换exit(1);替换失败的退出码设置为1}shellintstatus0;pidtretwaitpid(id,status,0);shell等待child退出if(ret0){printf(exitcode:d,WEXITSTATUS(status));打印child的退出码}}return0;}
  效果展示:
  说明:
  当执行。myshell命令后,便是我们自己实现的shell在进行命令行解释,我们自己实现的shell在子进程退出后都打印了子进程的退出码,我们可以根据这一点来区分我们当前使用的是Linux操作系统的shell还是我们自己实现的shell。

俞亮鑫海滩上的电车厢叮叮当,叮叮当,有轨电车曾驶过繁华的南京路外白渡桥,让许多上海市民对它都有一种怀旧情结。50年前,我们把这些旧电车厢搬到了荒凉的金山卫海滩安营扎寨。如果说,后来规模宏大的金山工程是福建龙海埭美古村盈盈河水环绕红砖古厝齐整美如画来源人民网原创稿人民网漳州9月8日电(苏海森)位于福建省漳州市龙海区的中国历史文化名村中国传统村落埭美古村,276座古厝傍水而建,呈轴对称排列,每一座房子格局大小一模一样,其规划之手撕渣男是假的?圈内人爆料娜扎没分手,徐开骋新剧被韩东君替代9月8日,知名娱记称,据圈内人透露,徐开骋古力娜扎现在还没分手,就是娜扎在北京,徐开骋每天都会去找她。从他们的对话中可以得知,徐开骋工作结束后,回酒店待了一会,大概有40分钟。然后年龄大了要忌口,建议中老年人牢记4多吃3少吃,别不当回事随着年龄的增长,人体的生理机能全面衰退,代谢缓慢,消化能力降低再也不能像年轻的时候那样,随意的胡吃海喝了,所以说年龄大了要忌口。50岁是人生的一个分水岭,过了50岁,便慢慢进入衰老再也不用担心充值卡打水漂!数字人民币硬核新场景落地,预付资金管理率先应用北京教培领域,更多场景待解锁点蓝字关注,不迷路你的身边有没有发生过这样的事情理发店健身房培训机构破产倒闭,老板卷款跑路,消费者预充值的钱打了水漂?现在,这个问题有了新的解决办法。9月8日,2022第二届中国(娱乐圈有多黑暗?细扒2022年日本最丑陋性丑闻事件,一言难尽文2号探秘人编辑2号探秘人性丑闻对日本的娱乐圈来说,容忍度究竟有多宽泛?那些表面风光,私底下却笼罩在视奸枕营业阴影下的日本女星,到底想要告诉我们什么?今天我们就来深度探讨一下。01北京各公园推出59项中秋文化活动多场直播邀民众云过佳节中新网北京9月8日电(徐婧)记者8日从北京市园林绿化局获悉,今年中秋假期,北京市各公园推出了59项特色活动。除传统的游园赏月民俗体验手工制作花卉展览等活动外,还增加了5G云赏月我们1937年,北京狐狸塔少女分尸案纪实英国外交官之女被人奸杀01白人女尸1937年冬天的一个早晨,北京已经寒风瑟瑟,由于战事吃紧,街道各处人烟稀少一个名叫张宝琛的老人,一大早沿着自己熟悉的胡同出门办事。就在路过城东南角楼一个被称作狐狸塔的地带大后备箱的电动快充小车,续航408KM,养车很便宜,奇瑞小蚂蚁开小车的感觉,要比大车更爽一些,尺寸设计小巧容易把控,底盘与路况无限衔接,地面反馈可以更直接传到方向盘上,以便驾驶者做好进一步操控。如今微型代步车销量很好,一是的确好开容易把控,二顺丰寄丢1。1万元iphone仅赔1000元,仗义的王卫为什么不全赔?顺丰快递,顺风顺水顺您心意。然而近日,使用顺丰快递的夏女士非但没有顺心意,反而十分闹心。什么原因呢?近日,深圳夏女士在顺丰邮寄了一台价值11000元iPhone13ProMax,结专家给华为泼冷水,捅破天的卫星通信技术被斥只是噱头?本文原创,禁止抄袭,违者必究近期,因为被台积电终止芯片代工而不断延期的华为Mate50系列正式发布,在网络之上引起了广泛关注,更引起了不少人在网上激烈讨论,其中最受关注的莫过于本次
iPhone14Plus市场表现毫无亮点但Pro的需求依然非常强劲投资分析公司摩根大通报告称,总体而言,iPhone14系列现阶段的销售情况好于前代产品,有迹象表明1月份从Android系统转入的用户比正常情况多。摩根大通最近下调了AAPL的目标拒绝黑色星期五,数字经济下一个牛标的!A股传来两个大利好,全面注册制下的大风口要来了。2023年即将迎来全面注册制时代,市场生态啊,出现了360度的大反转,周期的力量势不可当。这个板块呢,利好密集发布,逻辑够硬,位置够夏季连衣裙什么面料最舒服?夏季连衣裙搭配什么鞋子好看?炎热的夏天一天比一天热,连衣裙就成为了夏季唱主角的裙子。连衣裙的面料非常多,那么,夏季连衣裙什么面料最舒服?夏季连衣裙搭配什么鞋子好看?下面我们一起来看看吧!夏季连衣裙什么面料最舒河北4大古镇,比江南古镇小众,但却更独特,60岁前必去!头条免费正版图河北被称为燕赵大地,有句古话说燕赵大地多慷慨悲歌之士。而在这片古老的大地上,人杰地灵,物华天宝以及各种人文风俗,共同孕育出了独属于河北的旅游文化。游古镇是快速了解一座雄安新区纳税大户数字城市建设先锋中国联通高质量服务千年大计5G网络在城区县城干线及景区实现连续覆盖,河北省首个千兆城市,IPv6Ready全国第一城近日,数字中国建设整体布局规划引发热议,而在雄安新区,一幅未来之城数字化建设的壮丽画卷已经最近火了一种上衣叫杏衫,洋气显白,450岁女人穿正合适洒脱大气和精致的减龄感相互叠加,能够展示出今年春天别样的穿衣活力。在春季穿搭的大舞台上,那些能够分分钟撩拨心弦的单品,可以让年长女性也重焕年轻的光彩。所以我们要不断的修炼自己对于单快来围观!多项土壤微生物组合作成果荣登中科院1区Top期刊!氮循环(NitrogenCycle)过程是指氮元素在地球生物圈土壤圈等之间迁移转化和周转循环的过程,是生物圈内基本的物质循环之一。氮循环与微生物息息相关,许多氮转化反应都是由微生物难怪卫衣不兴了!今年流行的春衫好绝,配牛仔裤长裙好风情过往春秋换季,卫衣必有一席之地,然而今年几次出门踏青逛街,发现街上的美女们鲜少有穿卫衣的,大部分人的春衫都是薄款针织。可能大家会说,针织衫算什么新奇,谁没有似的?但事实上,今年流行高收益,流动性好,还安全?马甲理财流行意味着什么市面上涌现出一批类似存款性质的理财产品。(视觉中国图)现在的投资者既要收益高,又要流动性,还要安全,哪里去给他们找这样的资产啊。陈颖对南方周末记者说。她在上海一家股份制银行担任金融南财快评精准有力实施货币政策,为经济复苏和预期修复提供基础2023年3月3日,中国人民银行刘国强副行长在国新办新闻发布会表示,人民银行将根据经济形势变化适时适度调整货币政策。坚持正常的货币政策,保证正利率和向上的收益率曲线,不大水漫灌不大焦点分析3亿人每天用的快手,2023如何赚到更多的钱?文王雨佳编辑乔芊和3亿用户每天用的快手相比,6亿用户每天用的抖音,日活用户是前者的2倍。而中国短视频的TOP1和TOP2,两者赚钱能力的差距,远比其用户量的差距更夸张老大是老二的4
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网