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

会计可以做网站么seo公司赚钱吗

会计可以做网站么,seo公司赚钱吗,莱芜专注搜狗推广,做网站怎样收费的个人主页:chian-ocean 文章专栏-Linux 前言: 当一个进程发起某种操作(如I/O请求、信号、锁的获取等),但该操作需要的资源暂时不可用时,进程会被操作系统挂起,进入“等待队列”或“阻塞状态”。…

个人主页:chian-ocean

文章专栏-Linux

前言:

当一个进程发起某种操作(如I/O请求、信号、锁的获取等),但该操作需要的资源暂时不可用时,进程会被操作系统挂起,进入“等待队列”或“阻塞状态”。在此期间,进程不占用CPU,但仍保留其内存、文件描述符等资源

在这里插入图片描述

进程等待的必要性

僵尸进程的存在

僵尸进程的成因

  • 当子进程终止后,它的退出状态需要由父进程通过调用 wait()waitpid() 系统调用回收。
  • 如果父进程未回收子进程的退出状态,子进程会以“僵尸进程”的形式保留在进程表中。

特征:

  • 在 Linux 系统中,可以用 ps 命令查看,僵尸进程的状态为 Z(Zombie)。
  • 僵尸进程是操作系统保留的一个条目,主要用于父进程检查子进程的退出状态。

如下:

在这里插入图片描述

从图片中可以看到一个典型的 僵尸进程 的现象:

  • 进程 27864 被强制终止(kill -9 27864),但它的父进程(27863)没有调用 wait()waitpid() 来回收其子进程的退出状态。
  • 因此,27864 被标记为 <defunct> 状态,即僵尸进程。
  • ps 输出的 STAT 列中显示 Z+,这是僵尸进程的状态标识。

进程等待

进程等待是操作系统中一种重要的状态,指的是某个进程由于资源不足或条件未满足,暂时无法继续执行而被挂起的现象。

  • 使用 wait()waitpid() 回收子进程

wait ( )

参数:

  • int *status:
    
    • 用于保存子进程的状态信息(如退出码或终止信号)。
    • 如果不需要获取子进程状态,可以将其传入 NULL

返回值:

  • 成功:
    • 返回已终止的子进程的 PID。
  • 失败:
    • 返回 -1,并设置 errno
    • 常见错误包括:
      • ECHILD:当前进程没有子进程。
      • EINTR:调用被信号中断。

wait() 的作用

  1. 阻塞父进程:
    • wait() 会阻塞父进程,直到任意一个子进程状态发生变化(通常是终止)。
  2. 回收子进程资源:
    • 子进程终止后,其资源仍然保留在系统中,直到父进程调用 wait()waitpid() 回收它。
    • 如果父进程不调用 wait()waitpid(),子进程会变成 僵尸进程

示例:

#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>using namespace std;void childtast()
{for(int i = 0; i < 10; i++) // 循环打印从 0 到 9 的数字{cout << i << endl; // 输出当前的循环变量 i}sleep(3); // 睡眠 3 秒,模拟子进程的运行延迟
}int main()
{pid_t id = fork(); // 创建子进程cout << "id" << ":" << id << endl;if(id == 0) // 判断是否是子进程{sleep(3); // 子进程先睡眠 3 秒childtast(); // 子进程调用 childtast(),打印数字并睡眠}// 父进程等待任意一个子进程终止pid_t ret = wait(NULL); // 父进程调用 wait(),阻塞等待子进程终止if(ret == id) // 判断 wait() 返回的进程 ID 是否是创建的子进程 ID{cout << "ret" << ":" << ret << endl; // 输出子进程的 IDcout << "wait success" << endl; // 输出等待成功的消息}sleep(3); // 父进程再睡眠 3 秒,模拟延迟return 0;
}

fork() 创建子进程

  • 父进程和子进程同时运行。
  • 父进程的 id 是子进程的 PID,子进程的 id 是 0。

子进程的任务

  • 子进程先睡眠 3 秒,然后执行 childtast(),打印 09

父进程的等待

  • 父进程调用 wait(NULL),阻塞自身,直到子进程终止。
  • 当子进程完成任务并退出后,wait() 返回子进程的 PID。

父进程的后续操作

  • 父进程输出子进程的PID和等待成功的消息。
  • 父进程再睡眠 3 秒后退出。

waitpid ( )

waitpid()wait() 的增强版本,提供了更灵活的功能,允许父进程:

  1. 等待特定的子进程。
  2. 非阻塞等待子进程。
  3. 获取子进程的状态(如退出状态或被信号终止)。
pid_t waitpid(pid_t pid, int *status, int options);

参数说明

  • pid

    • pid > 0:等待特定的子进程(指定的 PID)。

    • pid == 0:等待与当前进程同一个进程组的任意子进程。

    • pid < -1:等待进程组 ID 为 |pid| 的任意子进程。

      wait(NULL) //等价于 waitpid(-1,NULL,0); 
      
    • pid == -1:等效于 wait(),等待任意子进程。

status 字段的结构

status

  • 指向一个整数的指针,用于存储子进程的状态信息(退出状态、信号等)。
  • 若不关心状态信息,可将其设为 NULL

在 Linux 系统中,status 是一个整数,表示子进程状态的多种可能性,底层通过位字段表示:

位字段含义
位 0-7子进程退出的信号或退出码(低 8 位)。
位 8-15退出状态(高 8 位,存储正常退出码)。
位 16-23暂停信号编号。

代码解析字段

#include<iostream> 
#include<unistd.h> 
#include<sys/types.h> 
#include<sys/wait.h> 
using namespace std;
int main()
{    pid_t id = fork();    cout << "id" << ":" << id <<endl;    if(id == 0)    {    sleep(3);    exit(1);       }    int status;    pid_t ret = waitpid(-1,&status,0);                                     if(ret == id)    {cout << "ret" << ":" << ret <<endl;    cout<< "wait success" <<endl;    }    cout <<"status :" << status << endl;cout << "退出码" << ((status >> 8)& 0xff ) <<" "<< "信号码" << (status & 0x7f)<< endl;return 0;
}
完整运行流程

fork() 创建子进程

  • 父进程创建子进程,并返回子进程的 PID。

子进程逻辑

  • 子进程休眠 3 秒后正常退出,退出码为 1

父进程逻辑

  • 父进程调用 waitpid() 阻塞等待子进程终止。
  • 获取子进程的状态信息,并解析退出码和信号码。

父进程输出状态信息

  • 输出子进程的 PID、状态值、退出码和信号码。

解析逻辑

解析退出码和信号编号
  • WIFEXITED(status)
    • 如果为真,表示子进程正常退出,其退出码存储在高 8 位。
    • 使用 (status >> 8) & 0xff 提取退出码。
  • WEXITSTATUS(status):== status & 0x7f
    • 获取退出码的宏,
    • 必须确保 WIFEXITED(status) 为真后使用。

options参数介绍

阻塞与非阻塞
特性阻塞非阻塞
进程状态等待资源时挂起,无法执行其他任务。立即返回,不会挂起,进程可执行其他任务。
适用场景简单任务、对实时性要求不高的任务。多任务并发、实时性要求高的任务。
复杂性实现简单,逻辑清晰。逻辑复杂,需要轮询或回调处理资源状态。
CPU 使用不浪费 CPU 资源,进程处于挂起状态。需要轮询资源状态,可能增加 CPU 占用。
资源管理等待资源的管理交由操作系统处理。需要程序主动检查资源状态,增加开发复杂度。

options

  • 用于指定额外的选项:
    • 0:阻塞等待。
    • WNOHANG:非阻塞等待。
    • WUNTRACED:返回暂停的子进程状态(子进程因 SIGSTOP 信号暂停)。
    • WCONTINUED:返回恢复运行的子进程状态(子进程因 SIGCONT 信号继续运行)。
WNOHANG
  • 非阻塞模式:
    • 如果没有子进程终止,waitpid() 会立即返回,而不是阻塞父进程。
  • 返回值:
    • 如果有子进程状态变化,则返回子进程的 PID。
    • 如果没有子进程状态变化,则返回 0
非阻塞轮询
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <chrono>
#include <thread>
using namespace std;
int main() {pid_t pid = fork(); // 创建子进程if (pid == 0) {// 子进程逻辑cout << "Child process running..." << endl;sleep(5); // 模拟子进程任务,延迟 5 秒cout << "Child process exiting..." << endl;exit(42); // 子进程以退出码 42 正常退出} else if (pid > 0) {// 父进程逻辑int status;while (true) {pid_t ret = waitpid(-1, &status, WNOHANG); // 非阻塞检查子进程状态if (ret == 0) {// 子进程尚未终止,父进程继续其他工作cout << "Child process still running. Parent doing other work..." << endl;this_thread::sleep_for(chrono::seconds(1)); // 模拟父进程任务} else if (ret > 0) {// 子进程已终止,解析状态if (WIFEXITED(status)) {cout << "Child process " << ret << " exited with code " << WEXITSTATUS(status) << endl;} else if (WIFSIGNALED(status)) {cout << "Child process " << ret << " was terminated by signal " << WTERMSIG(status) << endl;}break; // 结束轮询} else {// waitpid 出错perror("waitpid failed");break;}}} else {// fork 失败perror("fork failed");return 1;}return 0;
}

执行结果:

在这里插入图片描述

多进程下的进程等待

阻塞等待多个子进程

示例代码:等待所有子进程完成

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;int main() {// 创建多个子进程for (int i = 0; i < 3; ++i) {pid_t pid = fork();if (pid == 0) {// 子进程cout << "Child " << i << " (PID: " << getpid() << ") running..." << endl;sleep(2 + i); // 每个子进程休眠不同时间cout << "Child " << i << " (PID: " << getpid() << ") exiting..." << endl;exit(i); // 子进程以其序号为退出码}}// 父进程:等待所有子进程完成int status;while (true) {pid_t ret = wait(&status); // 阻塞等待任意一个子进程结束if (ret == -1) {// 没有子进程可等待时退出循环cout << "All child processes have finished." << endl;break;// 解析子进程状态if (WIFEXITED(status)) {cout << "Child process " << ret << " exited with code: " << WEXITSTATUS(status) << endl;} else if (WIFSIGNALED(status)) {cout << "Child process " << ret << " was terminated by signal: " << WTERMSIG(status) << endl;}}return 0;
}

代码执行:

在这里插入图片描述

非阻塞轮询等待多个子进程

示例代码:非阻塞等待多个子进程

通过 waitpid() 配合 WNOHANG 实现父进程的非阻塞轮询,定期检查是否有子进程完成。

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <chrono>
#include <thread>
using namespace std;int main() {// 创建多个子进程for (int i = 0; i < 3; ++i) {pid_t pid = fork();if (pid == 0) {// 子进程cout << "Child " << i << " (PID: " << getpid() << ") running..." << endl;sleep(2 + i); // 每个子进程休眠不同时间cout << "Child " << i << " (PID: " << getpid() << ") exiting..." << endl;exit(i); // 子进程以其序号为退出码}}// 父进程:非阻塞轮询等待所有子进程完成int status;int completed = 0; // 已完成的子进程计数while (completed < 3) {pid_t ret = waitpid(-1, &status, WNOHANG); // 非阻塞检查子进程状态if (ret > 0) {// 有子进程状态变化completed++;if (WIFEXITED(status)) {cout << "Child process " << ret << " exited with code: " << WEXITSTATUS(status) << endl;} else if (WIFSIGNALED(status)) {cout << "Child process " << ret << " was terminated by signal: " << WTERMSIG(status) << endl;}} else if (ret == 0) {// 没有子进程状态变化,父进程继续其他工作cout << "No child process exited yet. Parent doing other work..." << endl;this_thread::sleep_for(chrono::seconds(1)); // 模拟其他任务} else {// 错误处理perror("waitpid failed");break;}}cout << "All child processes have finished." << endl;return 0;
}

代码执行:

在这里插入图片描述

http://www.qdjiajiao.com/news/5085.html

相关文章:

  • 南宁响应式网站制作免费推广途径
  • 商业网站推广2022网络热词30个
  • 百度网站地址提交广告策划案优秀案例
  • 平原做网站网络服务器图片
  • 做化工贸易要用那些网站推广网络营销推广经验总结
  • 做网站 后端是谁来做的cms自助建站系统
  • 微信公众号服务号网站开发流程在线生成网页网站
  • 经营性网站备案怎么备案百度关键词网站排名优化软件
  • 各大网站地区是怎样和做的ip软件点击百度竞价推广
  • 企业建设网站的案例图片搜索图片识别
  • 官方网站建设合同网络营销的基本特征有哪七个
  • 深圳市官网网站建设平台做网站用什么软件
  • 网站站长在哪登陆后台如何推广app
  • 遵义市网站建设seo优化技术培训中心
  • 旅游网站开发 结束语优化教程
  • 西安模板网站建设安徽网络优化公司
  • 泰安网站建设培训新闻网站软文平台
  • 公司做个网站seo网站推广费用
  • 视频网站企业网站系统
  • 网站是如何做的好沧浪seo网站优化软件
  • zencart 一个产品网站下单去了外包简历就毁了吗
  • 静态网站添加到织梦公司推广文案
  • 怎么做投资网站不违法卢镇seo网站优化排名
  • wordpress system.css如何提升网站seo排名
  • 做网站设计多少钱查域名注册详细信息查询
  • 南阳市做网站网页设计与网站开发
  • 中国商标官方网站网络营销推广的渠道有哪些
  • 做网站必须知道的问题短网址链接生成
  • 郑州网站seo服务网站搭建策略与方法
  • 表白二维码制作网站seo外链怎么做