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

天水网站建设惠普合肥seo优化外包公司

天水网站建设惠普,合肥seo优化外包公司,贵阳市做网站的公司有哪些,做网站查询违章文章目录 一、进程等待1.1 意义 / 必要性1.2 进程等待的函数(wait / waitpid)1.3 status参数1.4 获取子进程status1.5 进程的阻塞等待与非阻塞等待 二、进程替换2.1 引言2.2 进程替换原理2.3 替换函数 一、进程等待 1.1 意义 / 必要性 为什么要有进程等…

文章目录

  • 一、进程等待
    • 1.1 意义 / 必要性
    • 1.2 进程等待的函数(wait / waitpid)
    • 1.3 status参数
    • 1.4 获取子进程status
    • 1.5 进程的阻塞等待与非阻塞等待
  • 二、进程替换
    • 2.1 引言
    • 2.2 进程替换原理
    • 2.3 替换函数

一、进程等待

1.1 意义 / 必要性

为什么要有进程等待? 我们知道,当子进程退出时,如果父进程不对其进行操作,子进程会变为僵尸进程。

而且当子进程结束时,我们如何知道子进程的最后执行情况呢?

父进程通过进程等待,可以:

  1. 回收子进程资源
  2. 获取子进程退出信息
  3. 同步操作

1.2 进程等待的函数(wait / waitpid)

wait函数

pid_t wait(int *status);
  • 该函数会暂停当前进程的执行,直到一个子进程结束。
  • 如果子进程已经结束,该函数会立即返回。
  • 函数返回值:执行成功 返回被等待进程pid,失败返回-1。
  • status参数:获取子进程的退出状态,不需要则设为null。

waitpid函数

pid_t waitpid(pid_t pid, int *status, int options);
  • 参数:

    • pid
      pid = -1,表示等待任意子进程
      pid = 0,等待进程id=pid 的子进程
    • status
      WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)
      WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)
    • option
      WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。
  • 该函数会暂停当前进程的执行,直到指定的子进程结束。

  • 返回值是结束子进程的进程ID,或者出错时的返回值。

主要的区别和用法总结如下:

  • wait函数只能等待任意子进程结束,而waitpid函数可以指定具体的子进程进行等待
  • waitpid函数提供了更多的选项,可以在等待子进程时指定不同的行为。
  • waitpid函数可以通过设置options参数来控制等待的方式,例如非阻塞、只等待指定状态等。
  • 在多进程的场景中,可以使用waitpid函数更灵活地管理子进程的状态。

1.3 status参数

  • waitwaitpid,都有一个status参数,该参数是一个输出型参数,由操作系统填充。
  • 如果 传递NULL,表示不关心子进程的退出状态信息
  • 否则,操作系统会根据该参数,将子进程的退出信息反馈给父进程

status是int型的整数,用于存储子进程的退出状态信息。其低7位(0-6位)第7位(第7位),其他位(8位及以上),分别存放不同信息。

进程正常终止情况下

  • 低八位(0-7位) 存储的是进程的退出状态。这个状态是由exit系统调用或者C语言中的exit函数传递给操作系统的。
  • 第八位:存储是否生成了core dump文件,如果生成了core dump文件,则该位会被置为1。
  • 高八位(16-31位) 通常被设置为0,用于标识进程的终止状态。

被信号终止情况下

  • 低八位 :存储的是导致进程终止的信号编号。当进程被信号终止时,状态的低八位会存储信号的编号,例如SIGSEGV表示段错误,SIGKILL表示进程被强制终止等。
  • 第8位 :存储是否生成了core dump文件,如果生成了core dump文件,则该位会被置为1。
  • 高八位 :通常被设置为0,用于标识进程的终止状态。

我们用位图来解释status

在这里插入图片描述

1.4 获取子进程status

我们通过下面一段代码 获取子进程status

// 程序获取进程status
int main() {pid_t id = fork();if (id == -1) {// 创建子进程失败perror("fork");exit(EXIT_FAILURE);} else if (id == 0) {// 子进程printf("子进程正在运行\n");exit(10);  // 子进程退出状态设为 10} else {// 父进程int status;pid_t iid = waitpid(id, &status, 0);printf("After the wait function\n");if(iid == id){printf("wait success, pid: %d, status: %d\n", iid, status);}sleep(10);}return 0;
}

代码执行结果如下

在这里插入图片描述

为什么我们给出退出码exit(10)而最后status值为2560?

根据上面status的存储分析:如果子进程正常退出,status 的值将会是子进程退出码的左移 8 位。

即前八位存储的是退出状态, 0000 1010 0000 0000,当我们返回其十进制后,即为2560。

1.5 进程的阻塞等待与非阻塞等待

意义

进程的阻塞等待和非阻塞等待是指在等待某个事件完成时,进程所采取的不同等待方式。

1. 阻塞等待(Blocking Wait)

  • 当一个进程进行阻塞等待时,它会暂时停止执行,并将控制权交给操作系统。进程将进入睡眠状态,直到所等待的事件发生或满足某个条件。
  • 在阻塞等待期间,操作系统会将进程从可运行状态转换为阻塞状态,并在事件发生后将进程重新唤醒。
  • 阻塞等待是一种同步等待方式,即进程会一直等待直到事件完成或超时。

2. 非阻塞等待(Non-blocking Wait)

  • 当一个进程进行非阻塞等待时,它会继续执行其他任务,而不会暂停等待。进程会周期性地检查所等待的事件是否已经发生或满足某个条件。
  • 如果事件已经发生,则进程可以立即处理该事件并继续执行。如果事件还未发生,则进程可能会继续轮询等待,或者进行其他操作。
  • 非阻塞等待是一种异步等待方式,即进程可以同时进行其他任务,而不必一直等待。

代码实现

1.5.1 进程阻塞等待

下面是代码实现:

int main()
{pid_t id = fork();if(id < 0) {// fork errorperror("fork error");exit(EXIT_FAILURE);}else if(id == 0) {// 子进程std::cout << "子进程正在运行, pid: " << getpid() << std::endl;exit(10);}else{// 父进程int status;pid_t rid = waitpid(id, &status, 0); // 阻塞等待,options设为0std::cout << "after wait" <<std::endl;if(rid == id && WIFEXITED(status)){std::cout << "wait success, pid: " << rid << ", status: " << status << std::endl;}else{std::cout << "子进程等待失败, return." << std::endl;return 1;}sleep(10);}return 0;
}

代码执行结果如下

在这里插入图片描述

1.5.2 进程非阻塞等待

代码实现如下:

int main()
{pid_t id = fork();if(id < 0){// errorperror("fork erorr");exit(EXIT_FAILURE);}else if(id == 0){printf("子进程正在运行,pid:%d \n", getpid());exit(10);}else{int status;pid_t rid;do{ // 有子进程退出时 rid返回其pidpid_t rid = waitpid(id, &status, WNOHANG);if(rid == 0){printf("child process is running\n");}sleep(5);}while(rid == 0);if(rid == id && WIFEXITED(status)){printf("wait success, child return code is :%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;
}

代码执行结果

在这里插入图片描述


二、进程替换

2.1 引言

首先,我们看下面一段代码:

#include <iostream>
#include <unistd.h>int main() {std::cout << "This is the original program." << std::endl;// 执行程序替换,将当前进程替换为/bin/ls(列出当前目录内容)char *args[] = {"/bin/ls", "-l", NULL};execv("/bin/ls", args);// 如果execv执行成功,下面的代码不会被执行std::cerr << "Failed to execute /bin/ls!" << std::endl;return 1;
}

代码的执行结果如下:

我们可以看到,程序运行后,执行了 ls -l 操作,而 Failed to execute /bin/ls! 并没有被打印到下面。

而ls本身也是一个程序,可以理解为,进程 被替换为了 ls 程序

2.2 进程替换原理

根据上面的图,我们分析进程替换原理,进程替换可以理解为下面的步骤:

  1. 加载新程序映像:操作系统会从磁盘上读取新程序的可执行文件,并将其加载到内存中。
  2. 创建新的页表:在加载新程序映像时,操作系统会创建一个新的页表来管理新程序所需的内存空间。
  3. 替换进程内容:一旦新程序映像加载到内存中,操作系统 会将当前进程的内容替换为新程序的内容(代码、数据和堆栈等)
  4. 开始执行新程序:替换完成后,控制权转移到新程序的入口点,新程序从那里开始执行

2.3 替换函数

像上面代码中所使用的execv函数,叫做程序替换函数:

下面列举这些程序替换函数,定义如下:

int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *filename, char *const argv[], char *const envp[]);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[]);

这些函数都是程序替换函数,它们的区别在于传递参数的方式和环境变量的处理:

  1. execv:
  • 参数:接受一个参数数组 argv,以及程序路径 path。
  • 示例:execv("/bin/ls", argv);
  1. execvp:
  • 参数:与execv 类似,但是可以通过环境变量 PATH 搜索可执行文件。
  • 示例:execvp("ls", argv);
  1. execve:
  • 参数:接受一个参数数组 argv,一个环境变量数组 envp,以及程序路径 filename。
  • 示例:execve("/bin/ls", argv, envp);
  1. execl:
  • 参数:接受多个参数,最后一个参数必须是 NULL,不接受参数数组,需要将每个参数单独列出。
  • 示例:execl("/bin/ls", "ls", "-l", NULL);
  1. execlp:
  • 参数:与execl 类似,但是可以通过环境变量 PATH 搜索可执行文件。
  • 示例:execlp("ls", "ls", "-l", NULL);
  1. execle:
  • 参数:与execl 类似,但是可以传递自定义的环境变量数组 envp。
  • 示例:execle("/bin/ls", "ls", "-l", NULL, envp);
http://www.mfbz.cn/news/318/

相关文章:

  • 东莞网站优化排名公司怎么在百度上注册店铺
  • 网站清除黑链百度怎么做网站
  • 提供盐城网站开发世界羽联巡回赛总决赛
  • 西安网站建设费用一键优化大师下载
  • 怎样在网站做宣传郑州网络推广方案
  • 企业独立官方网站网址怎么做网络游戏推广平台
  • 网站电子商务平台建设长沙正规seo优化价格
  • 网站备案换公司吗短视频seo询盘获客系统软件
  • struts2 做的网站平台推广公众平台营销
  • 聊城建网站服务seo推广案例
  • 公司网站制做nba今日最新消息
  • 自己开公司 自己做网站吗合肥百度关键词优化
  • 网站怎么做备案变更如何制作自己的网页链接
  • 如何快速建立一个网站鹤壁网站seo
  • 仪征做网站aicjoy网站建设优化收费
  • 如何给公司做网站百度百家号怎么赚钱
  • 创建网站忘记了怎么办百度店铺怎么开通
  • 做微信公众号网站源码郴州网站推广
  • 文化网站建设百度快速排名
  • 推荐坪山网站建设网站优化排名首页
  • 中国人可以做的c2c网站sem广告投放是做什么的
  • 网站么做淘宝客赚佣金谷歌排名网站优化
  • 无锡自助建网站b2b和b2c是什么意思
  • 广州市医院网站建设哪家好软件推广方案经典范文
  • 网站换主机换域名电话营销系统
  • 做网站需要注意什么问题网站维护收费标准
  • 在线制作手机网站镇江网站建设推广
  • 个人网站搭建模拟感想爱站关键词
  • wordpress 500 阿里云seo外包品牌
  • 阿里云怎么做静态网站网络营销专业可以干什么工作