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

seo和sem的关系为负关系优化措施最新回应

seo和sem的关系为负关系,优化措施最新回应,建设工程教育网网址,广州市住房城乡建设委网站文章目录 进程创建进程终止exit 和 _exit 函数 进程等待statuswaitwaitpid非阻塞轮询 进程替换进程替换函数 进程创建 创建进程其实就是使用fork(),fork()有两个返回值。如果创建成功就返回给父进程返回子进程的pid,给子进程返回0;创建失败就…

文章目录

  • 进程创建
  • 进程终止
    • exit 和 _exit 函数
  • 进程等待
    • status
    • wait
    • waitpid
    • 非阻塞轮询
  • 进程替换
    • 进程替换函数

进程创建

创建进程其实就是使用fork(),fork()有两个返回值。如果创建成功就返回给父进程返回子进程的pid,给子进程返回0;创建失败就给父进程返回-1。
因为有虚拟地址,父子进程看似代码和数据共享,其实会写时拷贝,在子进程修改数据时会开辟新空间。
在这里插入图片描述

进程终止

进程退出时的三种情况

  1. 代码运行完毕,结果正确。
  2. 代码运行完毕,结果不正确。
  3. 代码异常终止(进程崩溃)。

exit 和 _exit 函数

exit和_exit都会直接结束进程,不会执行后续任何代码

我们整个代码来看看exit和_exit的差别:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {printf("Hello");  // 无换行符,缓冲区未刷新// exit(0);        // 会触发清理和刷新缓冲区_exit(0);         // 直接退出,不执行清理和刷新return 0;
}

在这里插入图片描述

exit和exit的不同点

exit是c标准库,_exit是系统调用
exit执行刷新缓冲区,_exit不执行

在这里插入图片描述
执行return num等同于执行exit(num),因为调用main函数运行结束后,会将main函数的返回值当做exit的参数来调用exit函数。

进程等待

为了解决僵尸进程,获取子进程的退出信息我们需要使用进程等待。其中进程等待有两个关键的函数wait与waitpid。

#include<sys/types.h>
#include<sys/wait.h>pid_t wait(int*status);//成功返回被等待进程pid,失败返回-1
//返回的进程pid是随机的,如果有多个被等待的pid,它会随机选择一个
//status是输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

由上wait方法我们看到有个参数叫status,waitpid也有。

status

如果给status参数传NULL,表示会正常等待子进程结束,但是不获取子进程的退出状态。
否则操作系统会通过statu的参数,将子进程的退出信息反馈给父进程。

status虽然是一个整型变量,但status不能简单的当作整型来看待,因为status的不同比特位所代表的信息不同,一般我们只考虑低的16个比特位。

在status的低16比特位当中,高8位表示进程的退出状态,即退出码。进程若是被信号所杀,则低7位表示终止信号,而第8位比特位是core dump标志。

在这里插入图片描述
如果想要读取status退出状态或者终止信号的话,可以通过两个宏

WIFEXITED(status): 用于查看进程是否是正常退出,本质是检查是否收到信号。
WEXITSTATUS(status): 用于获取进程的退出码。

wait

wait的方法:

#include<sys/types.h>
#include<sys/wait.h>pid_t wait(int*status);//成功返回被等待进程pid,失败返回-1
//返回的进程pid是随机的,如果有多个被等待的pid,它会随机选择一个
//status是输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

我用一段代码演示父进程等待子进程结束然后获得子进程退出信息:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<sys/types.h>
int main()
{pid_t id = fork();//创建子进程if(id==0){//chlldint count=10;while(count--){printf("I am child:PID:%d,PPID:%d\n",getpid(),getppid());sleep(1);}exit(0);}//fatherint status=0;pid_t ret=wait(&status);//如果等待成功if(ret>0){printf("wait child success\n");if(WIFEXITED(status)){//退出正常printf("exit code:%d\n",WEXITSTATUS(status));}else{printf("exit signal:%d\n",status&0x7f);}}sleep(10);return 0;
}

子进程正常退出,父进程成功获取退出信息,子进程就不会形成僵尸进程
在这里插入图片描述
如果杀死了子进程,父进程一样是可以等待成功获取退出信号的

waitpid

waitpid方法:

#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid, int*status, int options);
//返回值和status都与wait是一样的,可以说wait是waitpid封装的一个函数,当pid==-1,option==0,那么waitpid==wait//第一个参数pid:
//pid > 0:等待进程 ID 等于 pid 的子进程
//pid == -1:等待任意子进程
//pid == 0:等待与调用进程(父进程)属于同一进程组的所有子进程//第三个参数options:
//options == 0,意味着这个选项没有任何用处,未开启选项
//options == WNOHANG,若pid指定的子进程没有结束,则waitpid直接返回0,不等待,若正常结束,则返回子进程pid 

用以下代码演示一下waitpid获取子进程退出码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
int main()
{pid_t id = fork();if (id == 0){//child          int count = 10;while (count--){printf("I am child...PID:%d, PPID:%d\n", getpid(), getppid());sleep(1);}exit(0);}//father           int status = 0;pid_t ret = waitpid(id, &status, 0);if (ret >= 0){//wait success                    printf("wait child success...\n");if (WIFEXITED(status)){//exit normal                                 printf("exit code:%d\n", WEXITSTATUS(status));}else{//signal killed                              printf("eixt siganl %d\n", status & 0x7F);}}sleep(10);return 0;
}

在这里插入图片描述

非阻塞轮询

在之前的父子进程关系中,当子进程还未退出时,父进程通常处于阻塞状态,这个期间父进程不能进程其他操作。
但是,我们可以采取非阻塞等待的方式。其实就是在调用waitpid时,给第三个参数optionsWNOHANG

//options == WNOHANG,若pid指定的子进程没有结束,则waitpid直接返回0,不等待,若正常结束,则返回子进程pid

不等待父进程就可以去做其他事。当被等待的子进程正常结束时,父进程就可以拿到子进程的退出信息:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main()
{pid_t id=fork();//创建子进程if(id==0){//childint count=3;while(count--){printf("child do something\n");sleep(3);}exit(0);}//fatherwhile(1){int status=0;pid_t ret=waitpid(id,&status,WNOHANG);if(ret>0){printf("wait success\n");printf("exit code:%d\n",WEXITSTATUS(status));break;}else if(ret==0){printf("father do other things\n");sleep(1);}else{//wait errorbreak;}}return 0;
}

在这里插入图片描述

进程替换

什么是进程替换:
共享代码和数据的父子进程,在修改子进程时就会发生写时拷贝。如果要修改子进程的代码,则需要进程替换
由下图可以了解到:

进程替换不是创建新的进程,仅仅是将代码和数据替换罢了,进程相关的PCB信息没有任何改变。

在这里插入图片描述

进程替换函数

进程替换函数可以让不同语言编写的程序串联起来!
进程替换可以使用的六个函数:

execl:执行指定路径的程序,参数以可变参数形式传递,必须以NULL结尾。
execlp:在系统的PATH环境变量中搜索程序并执行,参数以可变参数形式传递。
execle:执行指定路径的程序,允许传递环境变量数组envp,用于指定新程序的环境变量。
execv:执行指定路径的程序,参数以数组形式传递。
execvp:在系统的PATH环境变量中搜索程序并执行,参数以数组形式传递。
execvpe:在系统的PATH环境变量中搜索程序并执行,允许传递环境变量数组envp。

//库函数,它们6个最终都是调用的execve
#include <unistd.h>`
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],char *const envp[]);
//系统调用函数
int execve(const char *path, char *const argv[], char *const envp[]);

通过以上的介绍,我们可以发现它们的命名规律:

l: list,表示中间参数采用列表
p: path,自动搜索环境变量PATH
e: env,自己维护环境变量
v: vector,表示中间参数用数组

从最简单的execl函数介绍:

它的第一个参数就是路径,第一个参数到最后一个参数之间的参数叫做可变参数列表,也就是说可以有多个,它和我们在命令行使用的命令是一样的,只不过我们命令行的分隔是空格,而这里的分隔是逗号和引号,最后一个参数必是NULL,表示该表的末尾边界

execlp:

除了第一个参数和execl不一样以外,其他的格式都一样,p说明它会先从环境变量PATH中找,所以我们要执行命令可以不用带路径,直接写命令名字就行了,用execlp执行 ls -l -a命令的等效代码就是:
execlp("ls","ls","-l","-a",NULL);

execle:

execle函数,除了比execl多了一个最后一个参数以外,其他都不变,只是NULL值要在倒数第二个参数,同上方的代码应该是如下所示:
extern char** environ; execlp("/usr/bin/ls","ls","-l","-a",NULL,envrion);

传入execle的环境变量表也可以用用户定义的:

char* const my_environ[]
{	"SUPER=1","LITTLE=2","MONSTER=3",NULL	
};
execle("/usr/bin/ls","ls","-l","-a",NULL,my_environ);
int main()
{printf("my process\n");char* const my_environ[]={"SUPER=1","LITTLE=2","MONSTER=3",NULL};execle("/usr/bin/ls","ls","-l","-a",NULL,my_environ);printf("my process\n");return 0;
}

在这里插入图片描述
看起来和命令相同,实际上用户自定义的环境变量已经成为替换进程的一部分了。

这三个进程替换函数掌握了,剩下的接口参数都是类似的,想要自定义参数也是一样的操作。

http://www.dtcms.com/wzjs/46995.html

相关文章:

  • mongodb做网站佛山百度seo点击软件
  • wordpress 导入json天津百度seo推广
  • 网上书城网站开发说明书建站系统cms
  • 如何用天地图做网站推广有奖励的app平台
  • 新手如何学做网站网络公司的推广
  • 网站首页url是什么推广平台 赚佣金
  • 山西刚刚报的病毒seo英文全称
  • 某些网站域名解析错误企业培训机构排名
  • 网站架构师工资今日冯站长之家
  • 做ps兼职的网站有哪些产品推广方案范例
  • 做网站的服务器还需要空间吗关键词是怎么排名的
  • 匿名聊天网站怎么做太原网站快速排名优化
  • 做网站个网站要多少钱广告推广平台赚取佣金
  • 网站建设套餐是什么宁波网络营销推广公司
  • 网站兼容性问题百度入口的链接
  • 如何优化公司网站永久免费域名申请
  • 网站建设的关注点网站优化公司怎么选
  • 划分切片来做网站重庆公司seo
  • 免费行情软件app网站大全淘宝seo软件
  • wordpress 商品表单宁波seo外包公司
  • java能网站开发吗磁力搜索器
  • 网站登录页面盗号怎么做湖北搜索引擎优化
  • 全国网站开发赛seo流量是什么意思
  • 如何给网站做下载附件丹东seo推广优化报价
  • b2c网站建设百度seo运营工作内容
  • 创造与魔法官网站_一起做喜欢的事seo人人网
  • 深圳高端网站建设企业推广托管
  • 做网站要多少钱 知乎今日热点新闻头条排行榜
  • 加快政府网站建设的意见百度一下你就知道下载
  • 推广型网站开发软件四川seo优化