linux——进程(创建、终止、等待、替换)

进程的基本操作

概念
程序运行的一个实例,其占有一定的空间。

查询某一进程当前情况

ps  aux  |  grep  进程名

终止进程

kill  -9  pid;	//pid指需要终止的进程pid

创建

pid_t  fork();

该函数有两个返回值,对于子进程其返回的是0,对于父进程,其返回的是子进程的pid
fork函数一般在使用时都要用if语句进行分流,示例如下:

pid_t pid=fork();
if(pid==0)
{//子进程
}
else
{//父进程
}

我们用一段代码来证明fork函数的返回值情况。

   #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>int main(){pid_t pid=fork();if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());}else{printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());}return 0;}
 注:pid_t getpid();			获取当前进程pid;

其结果如下:
在这里插入图片描述
根据结果显示fork返回给父进程的值正是子进程的pid

退出

常见的退出方式有以下两种,exit函数是一种强制退出方式,return是一种常见的退出方式,其在效果上等同于exit函数。使用方法就不做赘述,与主进程中调用方式一样。

  1. void exit(int status);
  2. return;
    其实还有一种终止进程方式,就是调用system函数执行kill -9 命令终止进程,子进程自己终止自己我把它称为自杀,父进程终止子进程称为他杀,当然用子进程杀掉父进程也是可以的。代码如下:
 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){int i=0;pid_t pid=fork();if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());}else{char str[15]={0};sprintf(str,"kill -9 %d",pid);system(str);printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());while(1);}return 0;}

该方法可以杀掉子进程,但同样无法解决僵尸进程问题。

两种特殊的进程状态

僵尸进程:僵尸进程指子进程已退出但父进程未退出,此时子进程就会成为僵尸进程,即Z状态。僵尸进程的出现是因为子进程退出后没有释放资源造成的,故而僵尸进程会导致内存泄漏。如例:

 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){int i=0;pid_t pid=fork();pid_t ppid=0;if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());}else{printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());while(1);//父进程进入死循环}return 0;
}

结果如下:
在这里插入图片描述
由图可知,子进程成为僵尸进程
在这里插入图片描述
孤儿进程: 父进程退出但子进程未退出,子进程就会成为孤儿进程。如例:

 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){int i=0;pid_t pid=fork();pid_t ppid=0;if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());while(1);//子进程进入死循环}else{printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());}return 0;
}

结果如下:
在这里插入图片描述
在这里插入图片描述
由结果可知,子进程仍在运行,这是kill -9 杀掉进行。

进程等待

概念:
指子进程退出后,父进程对子进程的占用资源进行回收。故而进程等待可以避免僵尸进程的出现。

进程等待的两种方式

1、pid_t wait(int*status);		//等待任一进程结束返回值成功返回被等待进程pid,失败返回-1参数status指进程退出状态,不关心则可置为NULL2、pid_ t waitpid(pid_t pid, int *status, int options);返回值当正常返回的时候waitpid返回收集到的子进程的进程ID;如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;参数Pid=-1,等待任一个子进程。与wait等效。Pid>0.等待其进程ID与pid相等的子进程。status:WIFEXITED(status): 若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码)options:WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

如例:

1、pid_t wait(int*status);方式

 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){int i=0;pid_t pid=fork();pid_t ppid=0;if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());}else{wait(NULL);//等待子进程printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());while(1);//父进程进入死循环}return 0;
}

在这里插入图片描述
在这里插入图片描述

2、pid_ t waitpid(pid_t pid, int status, int options);方式

 #include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){int i=0;pid_t pid=fork();pid_t ppid=0;if(pid==0){printf("我是子进程,我的pid=%d\n",getpid());}else{int status;waitpid(pid,&status,0);//等待子进程printf("当前进程id=%d\n",pid);printf("我是父进程,我的pid=%d\n",getpid());while(1);//父进程进入死循环}return 0;
}

在这里插入图片描述
在这里插入图片描述
无论哪种方式,发现都没有出现僵尸进程

进程替换

概念
创建子进程成功后,其实这个子进程和其父进程具有相同的资源和代码,也就是说子进程将父进程的代码拷贝了一份为己有,父进程拥有的资源子进程也拥有,进程替换就是说将子进程原本的资源全部替换为你想要执行的可执行文件的资源,更通俗的说就是子进程的代码与你想要执行的可执行文件的代码相同,故而子进程就不具备与父进程相同资源的属性。
进程替换需要用到exec函数,其一共有6个,这里我们只说明execlp函数,该函数的参数较为麻烦,在此我将他写的更直白一些。

execlp("路径","路径","参数列表(可用NULL)")”路径“	就是说你想要替换的可执行文件的路径,要用绝对路径第二个参数与第一个参数相同第三个参数置为NULL即可

如例:

这是要用作替换的程序,我将其编译后生成名为out的可执行文件

 #include <stdio.h>#include <unistd.h>#include <sys/types.h>int main(){printf("已被替换\n");return 0;}

要执行的程序

 #include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>int main(){pid_t pid=fork();if(pid==0){         execlp("/home/kungege/stady/123/111","/home/kungege/stady/out",NULL);printf("我是子进程\n");}else{printf("我是父进程\n");}wait(NULL);return 0;}

其结果或许还会执行子进程中的 printf(“我是子进程\n”);,然而结果是
在这里插入图片描述
因为子进程当中的代码与父进程完全相同,一旦进程替换,子进程的代码就会变为替换的可执行文件的代码,故而printf(“我是子进程\n”); 不会执行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第 3-1 课:集合详解(上) + 面试题

先来看看集合的继承关系图,如下图所示: 其中: 外框为虚线的表示接口,边框为实线的表示类;箭头为虚线的表示实现了接口,箭头为实线的表示继承了类。为了方便理解,我隐藏了一些与本文内容无关的信息,隐藏的这些内容会在后面的章节中进行详细地介绍。 从图中可以看出,集…

CCNA 学习笔记(四)--路由协议(RIP)

现在我们先复习下&#xff0c;什么是路由&#xff1f;答&#xff1a;当路由器&#xff08;或者其它三层设备&#xff09;收到一个IP数据包时&#xff0c;会查看数据包的IP头部中的目的IP地址&#xff0c;并在路由表中进行查找&#xff0c;在匹配到最优路由后&#xff0c;将数据…

linux——进程间通信(管道)

概念 进程间通信是指子进程与父进程间的通信&#xff0c;一般用作父进程对子进程的控制或者子进程将其动向告诉父进程&#xff0c;由于进程是一个程序执行的实例&#xff0c;进程之间本身是无法进行通信的&#xff0c;故而运用一种管道将二者联系起来。当然管道并不只限于在父子…

第 3-2 课:集合详解(下) + 面试题

集合有两个大接口:Collection 和 Map,本文重点来讲解集合中另一个常用的集合类型 Map。 以下是 Map 的继承关系图: Map 简介 Map 常用的实现类如下: Hashtable:Java 早期提供的一个哈希表实现,它是线程安全的,不支持 null 键和值,因为它的性能不如 ConcurrentHashMap…

第 4-1 课:BIO、NIO、AIO 详解 + 面试题

IO 介绍 IO 是 Input/Output 的缩写,它是基于流模型实现的,比如操作文件时使用输入流和输出流来写入和读取文件等。 IO 分类 传统的 IO,按照流类型我们可以分为: 字符流字节流其中,字符流包括 Reader、Writer;字节流包括 InputStream、OutputStream。传统 IO 的类关系…

带头节点循环链表实现队列

队列的特征就是“先入先出”&#xff0c;入队时在链表的尾部插入数据&#xff0c;出队时删除掉头节点后面的节点&#xff0c;需要一个尾指针&#xff0c;始终指向链表的尾部&#xff08;新加进来的节点&#xff09;。具体请看原理图&#xff1a; 代码实现 #include <stdio…

第 3-4 课:数据结构——队列详解 + 面试题

队列(Queue):与栈相对的一种数据结构, 集合(Collection)的一个子类。队列允许在一端进行插入操作,而在另一端进行删除操作的线性表,栈的特点是后进先出,而队列的特点是先进先出。队列的用处很大,比如实现消息队列。 Queue 类关系图,如下图所示: 注:为了让读者更直…

GB/T 17710-1999 PHP生成校验码

校验码算法描述如下&#xff1a;详细&#xff1a;http://wenku.baidu.com/link?urlCDvNJ1sLYOPzbbxjEy5R-oME95RlfTCUU5-I5M0bqUt0I32b0Xd0EKmI-HiFQHhY8OcB6ERTml7pUwXFseLl8GGvkuc7w0V2sFDxi2H0XGC本例子以16位编号为例子&#xff0c;用PHP予以实现&#xff0c;代码如下&…

Linux——线程使用及互斥量

线程的基本操作 概念 线程是程序中的一个执行路线。每个程序当中至少有一个线程。 程序在执行的过程中是逐条执行的&#xff0c;按照代码的逻辑一次向下执行&#xff0c;所以无法同时完成两条指令&#xff0c;故而引进了线程&#xff0c;举个很简单的例子&#xff0c;如果同时…

安卓安装kali linux之Termux

本文讲述如何在手机上安装kali linux,我本想安装其他版本的linux,但不知是什么原因安装到一半就卡住&#xff0c;最终安装kali成功了&#xff0c;但也只是安装了kali的壳子&#xff0c;在inux上的操作都可以实现&#xff0c;只是工具并没有安装&#xff0c;后期可以自主安装工具…

液晶显示温度(DS18B20)

DS18B20测温范围-55——125度&#xff0c;在-10——85度之间精度为0.5度&#xff0c;其测温精度还是较高的&#xff0c;DS18B20常见封装为3个引脚&#xff0c;VCC(电源正)&#xff0c;DQ(信号线)&#xff0c;GND(电源负)&#xff0c;如图&#xff1a; DS18B20相关指令&#xf…

第 5-5 课:线程安全——synchronized 和 ReentrantLock + 面试题

前面我们介绍了很多关于多线程的内容,在多线程中有一个很重要的课题需要我们攻克,那就是线程安全问题。线程安全问题指的是在多线程中,各线程之间因为同时操作所产生的数据污染或其他非预期的程序运行结果。 线程安全 1)非线程安全事例 比如 A 和 B 同时给 C 转账的问题…

MFC中的几个常用类——CFileDialog

2019独角兽企业重金招聘Python工程师标准>>> 1 简介 CFileDialog类封装了Windows常用的文件对话框。常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能。 可以用 构造函数提供的方式使用CFileDialog&#xff0c;也可以从CFileDi…

Exchange Server2010部署完后的配置:CA、Outlook Anywhere、OWA域名简写

Exchange Server 2010邮件系统安装完成后&#xff0c;必须经过相应的配置后&#xff0c;才能使Exchange Server 2010邮件系统提供基本的访问、邮件收发等基本功能。下面我们逐一看看如何让Exchanger Server跑起来。Exchange Server2010产品授权&#xff1a;我们目前所安装的Exc…

STM32——PID恒温控制

原理 元件 stm32f103核心板、L298N模块(当然用MOS管更好)、led一个、NPN三极管一个、蜂鸣器一个、DHT11一个、LCD1602一个、电阻200欧两个、可调电阻10K一个、加热丝一个 功能描述 用DHT11检测当前环境温湿度&#xff0c;并将数据显示在LCD1602上&#xff0c;在用设定温度与当…

第 6-2 课:SpringMVC 核心 + 面试题

Spring MVC 介绍 Spring MVC(Spring Web MVC)是 Spring Framework 提供的 Web 组件,它的实现基于 MVC 的设计模式:Controller(控制层)、Model(模型层)、View(视图层),提供了前端路由映射、视图解析等功能,让 Java Web 开发变得更加简单,也属于 Java 开发中必须要…

Lync2013 升级错误总结8 Lync2013 日志总是提示进程 RtcHost(5724) 收到了一个无效的客户端证书...

错误提示&#xff1a;解决方法&#xff1a;1打开注册表引导到&#xff1a;HKLM\System\CurrentControlSet\Control\SecurityProviders\Schannel2 新建一个DWORD键值&#xff1a;值的名称&#xff1a;EnableSessionTicket3 右键这个值点编辑讲数值数据修改成&#xff1a;24 重新…

简易的遍历文件加密解密

功能描述 将生成的可执行程序放在指定的文件夹内&#xff0c;双击后将该目录下所有文件包括子文件夹内文件全部加密&#xff0c;再次双击运行后将进行解密。 加密解密实现 主要运用了异或与取反操作&#xff0c;异或&#xff1a;两个值不同为1&#xff0c;相同为0。取反就是将该…

安卓手机使用linux(含图形界面)——Aid Learning

以前再安卓手机上使用linux系统都是使用Termux&#xff0c;安装上很麻烦&#xff0c;而且还是黑乎乎的窗口&#xff0c;没有图形界面&#xff0c;对于初学linux者来说并不友好&#xff0c;而Aid Learning就更人性化了&#xff0c;他是一种模拟的linux,其安装十分简易&#xff0…

简易花式流水灯

先看看效果 具体思路 实现流水灯的效果其实就是控制相应的I/O口&#xff0c;以P2为例&#xff0c;通过有规律的改变P2各I/O口的状态就可实现相应规律的流水灯效果&#xff0c;这其中需要用到与、或、异或、左移、右移等操作。   流水灯向左闪烁点亮就是将P2最低位的1不断左移…