【Linux】初识系统调用&&进程状态_sigstop

进程id (PID)

首先我们来学习PID这个概念,PID全称Process ID,是标识和区分进程的ID。Linux系统保证不会同时存在两个进程拥有相同的PID,但在一个进程结束之后,其PID可能会再次被分配给新进程

父进程id(PPID)

每个进程除了一定有PID还会有PPID,也就是父进程ID,通过PPID可以找到父进程的信息。

为什么进程都会有父进程ID呢?因为进程都是由父进程衍生出来的

操作系统给我们提供了两个查看pid和ppid的系统接口

//所需的头文件
#include <sys/types.h>
#include <unistd.h>
//函数接口
pid\_t getpid(void);//查看进程ID
pid\_t getppid(void);//查看父进程ID

image-20221119204400248

运行结果:

image-20221119205305859


通过其他方式查看PID

首先我们想知道进程的PID,可以通过top或者ps命令来查看。

Top

在命令行执行top后,得到类似下面的输出

image-20221119205436415

PS

执行ps axj后输出如下,其中axj参数让ps命令显示更详细的参数信息。

image-20221119205532818

使用PID

拿到PID后,我们就可以通过kill命令来结束进程了,也可以通过kill -9或其他数字向进程发送不同的信号。

信号是个很重要的概念,我们后面会详细介绍,那么有了进程ID,我们也可以看看进程名字。


1.2 通过系统调用创建进程-fork初识

  • 运行 man fork 认识fork
  • 感性的知道fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)(后面章节细讲)
//头文件
#include <unistd.h>
pid\_t fork(void);

image-20221119210139804

从它的介绍中可以知道fork对父进程返回大于0的数字(本质上是子进程的pid),对子进程返回0,失败返回-1

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    int ret = fork();
    if(ret < 0)
    {
        perror("fork");
        return 1;
    }
    else if(ret == 0)
    { 	//child
	    printf("I am child : %d!, ret: %d\n", getpid(), ret);
    }else
    { 	//father
	    printf("I am father : %d!, ret: %d\n", getpid(), ret);
    }
    sleep(1);
    return 0;
}

image-20221119211321507
image-20221119211338326


2. 进程状态

看看Linux内核源代码怎么定义

根据进程的定义,我们知道进程是代码运行的实体,而进程有可能是正在运行的,也可能是已经停止的,这就是进程的状态。

网上有人总结进程一共5种状态,也有总结是8种,究竟应该怎么算呢,最好的方法还是看Linux源码。

下面的状态在kernel源代码里定义:

/\*
\* The task state array is a strange "bitmap" of
\* reasons to sleep. Thus "running" is zero, and
\* you can test for combinations of others with
\* simple bit tests.
\*/
static const char \* const task_state_array[] = {
  "R (running)",        /\* 0 \*/
  "S (sleeping)",        /\* 1 \*/
  "D (disk sleep)",    /\* 2 \*/
  "T (stopped)",        /\* 4 \*/
  "t (tracing stop)",    /\* 8 \*/
  "X (dead)",        /\* 16 \*/
  "Z (zombie)",        /\* 32 \*/
};

这真的是Linux的源码,可以看出进程一共7种状态,含义也比较清晰,注意其中D(disk sleep)称为不可中断睡眠状态(uninterruptible sleep)。

  • R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
    里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
    (interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的
    进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可
    以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态

查看状态

通过ps aux可以看到进程的状态。

O:进程正在处理器运行,这个状态从来没有见过.
S:休眠状态(sleeping)
R:等待运行(runable)R Running or runnable (on run queue) 进程处于运行或就绪状态
I:空闲状态(idle)
Z:僵尸状态(zombie)
T:T停止状态(stopped)
D: 不可中断的深度睡眠,一般由IO引起,同步IO在做读或写操作时,cpu不能做其它事情,只能等待,这时进程处于这种状态,如果程序采用异步IO,这种状态应该就很少见到了

其中就绪状态表示进程已经分配到除CPU以外的资源,等CPU调度它时就可以马上执行了。运行状态就是正在运行了,获得包括CPU在内的所有资源。等待状态表示因等待某个事件而没有被执行,这时候不耗CPU时间,而这个时间有可能是等待IO、申请不到足够的缓冲区或者在等待信号。


Z(zombie)-僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)
没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

一个创建维持30秒的僵死进程例子 :

#include <stdio.h>
#include <stdlib.h>
int main()
{
	pid\_t id = fork();
	if (id < 0){
		perror("fork");
		return 1;
	}
	else if (id > 0){ //parent
		printf("parent[%d] is sleeping...\n", getpid());
		sleep(30);
	}
	else{
		printf("child[%d] is begin Z...\n", getpid());
		sleep(5);


为了做好运维面试路上的助攻手,特整理了上百道 **【运维技术栈面试题集锦】** ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,**小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。**

![](https://img-blog.csdnimg.cn/img_convert/4e1af79cab035f0dcc9ef88e0f2e94e2.png)

本份面试集锦涵盖了

*   **174 道运维工程师面试题**
*   **128道k8s面试题**
*   **108道shell脚本面试题**
*   **200道Linux面试题**
*   **51道docker面试题**
*   **35道Jenkis面试题**
*   **78道MongoDB面试题**
*   **17道ansible面试题**
*   **60道dubbo面试题**
*   **53道kafka面试**
*   **18道mysql面试题**
*   **40道nginx面试题**
*   **77道redis面试题**
*   **28道zookeeper**

**总计 1000+ 道面试题, 内容 又全含金量又高**

*   **174道运维工程师面试题**

> 1、什么是运维?

> 2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

> 3、现在给你三百台服务器,你怎么对他们进行管理?

> 4、简述raid0 raid1raid5二种工作模式的工作原理及特点

> 5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

> 6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

> 7、Tomcat和Resin有什么区别,工作中你怎么选择?

> 8、什么是中间件?什么是jdk?

> 9、讲述一下Tomcat8005、8009、8080三个端口的含义?

> 10、什么叫CDN?

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

> 17、如何重置mysql root密码?
加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
件?什么是jdk?

> 9、讲述一下Tomcat8005、8009、8080三个端口的含义?

> 10、什么叫CDN?

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

> 17、如何重置mysql root密码?
加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值