Linux☞进程控制
在终端执行命令时,Linux会建立进程,程序执行完,进程会被终止;Linux是一个多任务的OS,允许多个进程并发运行;
Linxu中启动进程的两种途径:
①手动启动(前台进程(命令gedit)...后台进程(命令+‘&’))
②调度启动 --at/cron启动
at执行的命令一般不会在终端回显,可以采用重定向到文件就可以查看;
Linux环境下常见的进程操作命令:
ps--查看系统中的进程;
top--动态显示系统中的进程;
kil--终止进程(包括后台进程);
Linux环境下的进程会有一个唯一的进程标识符(pid),进程标识有进程号PID和它的父进程号PPID,PID唯一标识一个进程,其中,PID和PPID都是非零正整数。获得当前进程的PID和PPID的系统调用是getpid()和getppid()函数【头文件unistd.h】;
ps -ef|grep test1 (可以查找程序test1.c运行时的进程号);
3个特殊进程:
PID为0的调度进程,是内核的一部分,也被称为交换进程和系统进程;
PID为1的init进程(centos6及之前版本),init进程是内核启动并运行的第一个用户进程(不是内核中的系统进程),负责对系统进行初始化,并将系统引导到某个状态。init进程不能被终止。
PID为2的kthreadd内核进程,其是一个内核线程,负责执行后台操作。
进程相关函数:
exec函数族--在进程中启动另一个程序执行;
system--在进程中开始另一个进程;
fork--从已经存在的进程中复制一个新进程
sleep--让进程暂停运行一段时间;
exit/_exit--用来终止进程
wait/waitpid--暂停父进程,等待子进程完成运行;
Fork函数
进程调用一次fork函数创建一个新进程,新创建的新进程被称为子进程。该函数调用一次但是返回两次,子进程返回值是0,父进程返回新的子进程的pid。父、子进程并不共享这些存储空间部分,通常父、子进程共享代码段;子进程继承父进程的以下属性:已打开的文件描述符 实际UID、GID,有效UID、GID 当前工作目录 根目录 文件创建UMASK 环境 资源限制
exec函数族
例6-3:用fork函数创建一个子进程,在子进程中。要求显示子进程号和父进程号,然后显示当前目录下的文件信息,在父进程中同样显示子进程号和父进程号;
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{pid_t result;int newret;result=fork();if(result==-1){printf("进程创建失败");}else if(result==0){printf("返回值是:%d,这是子进程,进程号是:%d\n",result,getpid());printf("父进程号是:%d\n",getppid());execl("/bin/ls","ls","-l",0);}else{sleep(10);printf("返回值是:%d,这是父进程,进程号是:%d\n",result,getpid());printf("父进程号是:%d\n",getppid());}
}
total后是ls列出的内容,![]()
exec族的6个函数来建立子进程分别是execl、execv、execle、execve、execlp、execvp函数;其中l、e、v、p表示函数中的参数分别用列表传递方式、字符指针数组传递方式、可指定环境变量及路径自动搜索功能;
exec示例:
char *const ps_argv[]={"ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL};
char *const ps_envp[]={"PATH=/bin:/user/bin","TERM=console",NULL};
execl("/bin/ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL);
execv("/bin/ps",ps_argv);
execle("/bin/ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL,ps_envp);
execve("/bin/ps",ps_argv,ps_envp);
execlp("ps","ps","-o","pid,ppid,pgrp,session,tpgid,comm",NULL);
execvp("ps",ps_argv);
exec应用:
1.execv函数的使用,要在程序中执行命令:ps -ef,命令ps在’/bin‘目录下,在这一函数中,参数v表示参数传递(含命令)为构造指针数组方式;
char* arg[]={"ps","-ef",NULL};
函数的使用:
execv("/bin/ps",arg);
【ps命令参数】
-e 显示所有进程(等价于-A)
-f 全部列出,通常和其他选项联用】
//参考程序为:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{char *argv[]={"ps","-ef",NULL};execv("/bin/ps",argv);return 1;
}
2.execlp函数的使用,在程序中执行命令:ps -ef,命令ps在‘/bin’目录下,在这一函数中,参数l表示命令或参数逐个列举,参数p是文件查找方式(自动检索路径而不需要给出路径),函数调用形式:
execlp("ps","ps","-ef",NULL);
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{execlp("ps","ps","-ef",NULL);return 1;
}
3.execl函数应用,在程序中执行命令:ps -ef,命令ps在‘/bin’目录下,在这一函数中,参数l表示命令或参数逐个列举,需要给定路径,函数调用形式如下:
execl("/bin/ps","ps","-ef",NULL);
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{execl("/bin/ps","ps","-ef",NULL);return 1;
}
4.execle函数应用,execle("/bin/login","login","-p",username,NULL,envp);上述语句运行时,login提示用户输入密码,输入密码期间关闭终端的回显,然后验证密码的正确性,如果密码不正确,login终止,init会重新fork/exec一个getty进程。如果密码正确,login程序设置一些环境变量,并设置当前的工作目录位用户的主目录;
5.设计程序,在子进程中调用函数execl(''/bin/ps","ps","-ef",NULL),而在父进程中调用函数execle("/bin/env","env",NULL,envp),其中定义:char *envp={"PATH=/tmp","USER=liu",NULL};
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{char *envp[]={"PATH=/tmp","USER=liu",NULL};pid_t result;result=fork();if(result==-1){printf("创建进程失败!\n");}else if(result==0){printf("创建进程成功\n");execl("/bin/ps","ps","-ef",NULL);}else{sleep(5);printf("父进程\n");execle("/bin/env","env",NULL,envp);}return 1;
}
//测试程序,先输出“创建进程成功”,之后运行ps- ef命令,停顿5秒后,输出"父进程",显示env命令内容:
PATH=/tmp
USER=liu
进程终止的两种形式:
①正常终止:main返回、调用exit函数、调用_exit系统调用;
②异常终止:被信号终止、调用absort,使其产生SIGABRT信号;
exit函数、_exit系统调用区别:
设计程序使得子进程和父进程在显示输出一些文字后用_exit和exit函数终止进程;
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{pid_t result;result=fork();if(result==-1){printf("创建进程失败!\n");exit(0);}else if(result==0){printf("测试终止进程的_exit函数\n");printf("目前为子进程,这一行我们用缓存!");_exit(0);}else{sleep(5);printf("测试终止进程的exit函数\n");printf("目前为父进程,这一行我们用缓存!");exit(0);}return 1;
}

printf函数使用的是缓冲I/O方式,在遇到‘\n’换行符时,自动将缓冲区的记录读出;在调用exit函数时,会先调用退出处理函数,然后清理I/O缓冲区,最后执行exit系统调用,而_exit函数则是直接调用exit系统调用,因此无法正常输出缓冲区的内容;
如果在子进程中调用sleep(5),父进程不调用会出现:
XXX![]()
僵尸进程
一个已经终止运行、但其父进程还没对其进行善后处理(获得终止子进程的有关信息、释放它所占有的资源)的进程;
使用fork创建的子进程,在父进程已经结束,但其还在继续运行,子进程进入无父进程的状态,称之为孤儿进程;孤儿进程会很快被init/systemd所收养;另外,为避免这种情况,可以通过在父进程中调用wait函数/waitpid函数,使得子进程比父进程早终止;
示例:僵尸进程的产生
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main()
{pid_t result;result=fork();if(result==-1){printf("创建进程失败!\n");exit(0);}else if(result==0){printf("这是子进程,进程号是:%d\n",getpid());}else{wait(NULL); //init系统消除僵尸进程;sleep(20);printf("这是父进程,进程号是:%d\n",getpid());}return 1;
}
一个程序退出时,它的子进程会被init进程继承,它是Linux启动后的第一个进程,init进程会自动清理所有它所继承的僵尸进程。
例:在父进程中调用wait函数等待子进程,父进程直到接收到子进程结束的信号后,父进程结束等待。设计一个程序,要求创建一个子进程,子进程显示自己的进程号pid后暂停一段时间,父进程等待子进程正常结束,打印显示等待的进程号pid和等待的进程退出状态。
//待定
相关文章:
Linux☞进程控制
在终端执行命令时,Linux会建立进程,程序执行完,进程会被终止;Linux是一个多任务的OS,允许多个进程并发运行; Linxu中启动进程的两种途径: ①手动启动(前台进程(命令gedit)...后台进程(命令‘&’)) ②…...
mybatis离谱bug乱转类型
字符串传入的参数被转成了int: Param("online") String online<if test"online 0">and (heart_time is null or heart_time <![CDATA[ < ]]> UNIX_TIMESTAMP(SUBDATE(now(),INTERVAL 8 MINUTE)) )</if><if test"…...
视频监控管理平台LntonCVS视频汇聚平台充电桩视频监控应用方案
随着新能源汽车的广泛使用,公众对充电设施的安全性和可靠性日益重视。为了提高充电桩的安全管理和站点运营效率,LntonCVS公司推出了一套全面的新能源汽车充电桩视频监控与管理解决方案。 该方案通过安装高分辨率摄像头,对充电桩及其周边区域进…...
VS环境Python:深度探索与实用指南
VS环境Python:深度探索与实用指南 在编程领域,VS环境(Visual Studio环境)与Python的结合,为开发者们提供了一种强大而灵活的开发体验。这种结合不仅提升了开发效率,还增强了代码的可读性和可维护性。然而&…...
SpringBoot整合SpringSecurit(二)通过token进行访问
在文章:SpringBoot整合SpringSecurit(一)实现ajax的登录、退出、权限校验-CSDN博客 里面,使用的session的方式进行保存用户信息的,这一篇文章就是使用token的方式。 在其上进行的改造,可以先看SpringBoot…...
【算法训练 day50 打家劫舍、打家劫舍Ⅱ、打家劫舍Ⅲ】
目录 一、打家劫舍-LeetCode 198思路 二、打家劫舍Ⅱ-LeetCode 213思路 三.打家劫舍Ⅲ-LeeCode 337思路 一、打家劫舍-LeetCode 198 Leecode链接: leetcode 198 思路 dp数组含义为:当前数组范围下能偷到的最多的钱。递推公式为:dp[j] max(dp[j-2]nums[j],dp[j-1…...
YOLOv8改进 | 卷积模块 | 在主干网络中添加/替换蛇形卷积Dynamic Snake Convolution
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 蛇形动态卷积是一种新型的卷积操作,旨在提高对细长和弯曲的管状结构的特征提取能力。它通过自适应地调整卷积核的权重࿰…...
深入解析力扣183题:从不订购的客户(LEFT JOIN与子查询方法详解)
关注微信公众号 数据分析螺丝钉 免费领取价值万元的python/java/商业分析/数据结构与算法学习资料 在本篇文章中,我们将详细解读力扣第183题“从不订购的客户”。通过学习本篇文章,读者将掌握如何使用SQL语句来解决这一问题,并了解相关的复杂…...
牛客NC32 求平方根【简单 二分 Java/Go/C++】
题目 题目链接: https://www.nowcoder.com/practice/09fbfb16140b40499951f55113f2166c 思路 Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** para…...
王道408数据结构CH3_栈、队列
概述 3.栈、队列和数组 3.1 栈 3.1.1 基本操作 3.1.2 顺序栈 #define Maxsize 50typedef struct{ElemType data[Maxsize];int top; }SqStack;3.1.3 链式栈 typedef struct LinkNode{ElemType data;struct LinkNode *next; }*LiStack;3.2 队列 3.2.1 基本操作 3.2.2 顺序存储…...
Angular 由一个bug说起之六:字体预加载
浏览器在加载一个页面时,会解析网页中的html和css,并开始加载字体文件。字体文件可以通过css中的font-face规则指定,并使用url()函数指定字体文件的路径。 比如下面这样: css font-face {font-family: MyFont;src: url(path/to/font.woff2…...
并查集进阶版
过关代码如下 #define _CRT_SECURE_NO_WARNINGS #include<bits/stdc.h> #include<unordered_set> using namespace std;int n, m; vector<int> edg[400005]; int a[400005], be[400005]; // a的作用就是存放要摧毁 int k; int fa[400005]; int daan[400005]…...
贪心(不相交的开区间、区间选点、带前导的拼接最小数问题)
目录 1.简单贪心 2.区间贪心 不相交的开区间 1.如何删除? 2.如何比较大小 区间选点问题 3.拼接最小数 1.简单贪心 比如:给你一堆数,你来构成最大的几位数 2.区间贪心 不相交的开区间 思路: 首先,如果有两个…...
[力扣题解] 617. 合并二叉树
题目:617. 合并二叉树 思路 递归法遍历,随便一种遍历方式都可以,以前序遍历为例; 代码 class Solution { public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if(root1 NULL){return root2;}if(root2 NULL){r…...
kafka-消费者组(SpringBoot整合Kafka)
文章目录 1、消费者组1.1、使用 efak 创建 主题 my_topic1 并建立6个分区并给每个分区建立3个副本1.2、创建生产者发送消息1.3、application.yml配置1.4、创建消费者监听器1.5、创建SpringBoot启动类1.6、屏蔽 kafka debug 日志 logback.xml1.7、引入spring-kafka依赖1.8、消费…...
Redisson知识
使用Redission获取锁 RLock lock redisson.getLock("my-lock"); 一、Redisson使用不指定锁过期时间的方式加锁: lock.lock(); 特点: 1.使用Redisson加的锁,具有自动续期机制,如果业务运行时间较长,运行…...
0103__【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C 单线程性能分析工具 Gprof】 GNU的C/C 性能分析工具 Gprof 使用全面指南-CSDN博客...
如何把几个pdf文件合成在一个pdf文件
PDF合并,作为一种常见的文件处理方式,无论是在学术研究、工作汇报还是日常生活中,都有着广泛的应用。本文将详细介绍PDF合并的多种方法,帮助读者轻松掌握这一技能。 打开 “轻云处理pdf官网” 的网站,然后上传pdf。 pd…...
Stream与MLC测试CPU内存DDR5的原理与方法详解
在高性能计算和服务器领域,内存性能是决定整体系统性能的关键因素之一,特别是随着DDR5内存的普及,其更高的带宽和更低的延迟特性使得内存性能测试变得更加重要。本文将详细介绍使用Stream和MLC两种工具对CPU内存DDR5进行性能测试的原理和实施…...
linux业务代码性能优化点
planning优化的一些改动----------> 减少值传递,多用引用来传递 <---------- // ----------> 减少值传递,多用引用来传递 <---------- // 例1: class A{}; std::vector<A> v; // for(auto elem : v) {} // 不建议ÿ…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
Linux-进程间的通信
1、IPC: Inter Process Communication(进程间通信): 由于每个进程在操作系统中有独立的地址空间,它们不能像线程那样直接访问彼此的内存,所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...
HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...
