Linux多进程开发-常用命令

进程

进程是计算机中正在运行的程序的实例。每个进程都有自己的地址空间、内存、文件和设备、线程以及其他系统资源。操作系统通过调度和管理进程来实现多任务处理,使得多个进程可以同时运行并与用户交互。在操作系统中,进程是基本的资源分配单位,它可以独立运行,也可以与其他进程进行通信和协作。

进程是程序的一次运行活动。

常用命令

在linux系统中,有几个常用的命令对进程进行操作。查看进程命令ps和top。结束进程命令kill,以及管道和重定向命令。

  1. 静态显示系统进程信息(ps)

    ps指令是linux系统标准的进程查看工具,通过它可以查看系统中进程的详细信息

    常用参数有:

    a:显示所有进程(包括其他用户的进程)
    u:以用户为主的格式来显示进程情况
    x:显示没有控制终端的进程
    e:显示环境变量
    f:做全格式列出
    l:长格式显示
    r:只显示正在运行的进程
    p:按照进程ID列出进程
    

    例子:

    ps            # 显示当前用户进程
    ps -aux       # 显示全部跟用户有关进程的所有信息
    

    常与管道组合使用:

    ps -aux |grep a    # 显示有关a进程的所有信息
    
  2. 动态显示系统进程信息(top)

    top命令相当于windows系统中的任务管理器,top是一个动态显示的过程,他通过不断的刷新当前的状态以动态的显示进程。调用top之后,它将独占前台,直到用户终止该程序(ctrl + c)。

    语法:

    top [-d] | top [-bnp]
    

    常用参数:

    -b:以批处理模式操作。
    -c:显示完整的命令行。
    -d:屏幕刷新间隔时间。
    -I:忽略失效过程。
    -s:保密模式。
    -S:累积模式。
    -i:不显示闲置和僵死进程。
    -n:更新显示次数。
    

进程标识符

每个进程都有一个非负整数表示唯一的ID,叫做pid,类似我们的身份证。

编程调用getpid函数获取本身的进程标识符,调用getppid获取父进程的进程标识符。

Linux进程控制

进程创建

在Linux系统中,创建进程的方式有两种:操作系统创建,和父进程创建。操作系统创建的进程是平等关系的,而父进程创建的子进程不是平等关系,而且相互之间存在资源继承的关系。而且父进程创建的子进程又可以创建子进程,从而形成一个进程家族。

fork函数

系统创建进程的通用方法是使用函数fork();我们通过在Linux终端输入man 2 fork命令,我们看到fork的使用说明。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=e0575ecf287cebd8c3d514274b6e31de
.png&pos_id=img-S99QMrCK-1733831801522)

该函数的返回类型为整形,若是父进程则放回值为一个正整数,是子进程的pid号。若为子进程,则返回值为0。我们可以写段代码进行试验。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t pid;printf("befor fork\n");printf("father process pid = %d \n",getpid());pid = fork();if(pid > 0){printf("this is father;pid = %d\n",getpid());}else if(pid == 0){printf("this is son; pid = %d\n",getpid());}return 0;
}

我们看到以下结果:在这里插入图片描述

如果你使用man命令,发现他找不到这些,出现以下情况:

在这里插入图片描述

不要慌,按照以下步骤操作一下。

# 1、更新一下资源
sudo apt-get update   
# 2、安装标准c相关的帮助文档
sudo apt-get install libc-dev
sudo apt-get install glibc-doc
vfork函数

man 2 vfork命令看到的结果

#include <sys/types.h>
#include <unistd.h>pid_t vfork(void);

我们看到与fork函数一个样子,该函数也是放回一个整形,也是创建一个新的进程,但是他们两个函数是不一样的。与fork函数作比较,虽然功能和参数都类似,但是也有自己的独特之处。例如:

  1. fork函数创建子进程是对父进程的完全拷贝,所谓完全拷贝就是将父进程的代码完全复制一份运行,这样子子进程就能完全独立于父进程运行,这样子的代码具有良好的并发性;而vfork函数创建的子进程,是和父进程共享地址空间,子进程需要完全运行在父进程的地址空间上,子进程对地址空间的数据修改同样会影响到父进程。
  2. vfork函数创建的子进程会优先运行,当它执行完exit或者exec后,父进程才可以运行;而fork函数创建的子进程运行的优先级取决于系统的调度算法。

由于vfork函数不会复制父进程的地址空间,会节省系统大量的开销,运行速度也非常快。

我们同样可以用几个代码来看看效果。

首先我们用fork函数来写一段代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;int cnt = 0;printf("befor fork\n");printf("father process pid = %d \n",getpid());pid = fork();if(pid > 0){while(1){printf("this is father;pid = %d\n",getpid());sleep(2);printf("father: %d \n",cnt);}}else if(pid == 0){while(1){cnt ++;printf("this is son; pid = %d\n",getpid());sleep(2);if(cnt >= 5){printf("the son exit\n");exit(0);}}}return 0;
}

运行结果如下:

hyx@hyx-virtual-machine:~/c_project/c_Process$ ./a.out
befor fork
father process pid = 6759
this is father;pid = 6759
this is son; pid = 6760
father: 0
this is father;pid = 6759
this is son; pid = 6760
father: 0
this is father;pid = 6759
this is son; pid = 6760
father: 0
this is father;pid = 6759
this is son; pid = 6760
^C

通过运行结果我们看到,父进程和子进程在同时运行,并且在父进程中,子进程更改了值,但是父进程这边没有。

那这边用vfork修改一下代码

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;int cnt = 0;printf("befor fork\n");printf("father process pid = %d \n",getpid());pid = vfork();if(pid > 0){while(1){printf("this is father;pid = %d\n",getpid());sleep(2);printf("father: %d \n",cnt);}}else if(pid == 0){while(1){cnt ++;printf("this is son; pid = %d\n",getpid());sleep(2);if(cnt >= 3){printf("the son exit\n");exit(0);}}}return 0;
}

运行结果:

befor fork
father process pid = 6975
this is son; pid = 6976
this is son; pid = 6976
this is son; pid = 6976
the son exit
this is father;pid = 6975
father: 3
this is father;pid = 6975
father: 3
this is father;pid = 6975
^C

通过结果我们发现,vfork函数创建的子进程会优先执行,在调用exit函数之后,父进程才开始运行,并且在子进程中对cnt的值进行了修改,在父进程中这个值也被修改了。


进程等待

在Linux系统中,当多个进程同时进行的时候,进程间需要协作工作,可能用到进程等待的操作。进程间的等待包括父子进程间的等待和进程组内成员间的等待。

同时用了wait方法接受推出的状态,如果子进程退出状态,没有被收集,子进程将变成僵尸进程。

进程等待有两种方法:wait和waitpid。
在Linux系统终端中使用帮助命令main wait,得到函数以下信息:

#include <sys/types.h>
#include <sys/wait.h>pid_t wait(int *wstatus);pid_t waitpid(pid_t pid, int *wstatus, int options);
wait函数

wait函数返回类型为整形,wstatus为一个整形指针,用于存放子进程的结束状态。当wait被调用时,父进程处于挂起状态,只有当子进程结束返回。如果wait调用的父进程没有子进程,则返回失败。

调用成功:返回等待状态进程的pid; 调用失败:返回-1

我们同样用上面的代码的基础上,进行简单 的修改来看看情况。

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;int cnt = 0;int status;printf("befor fork\n");printf("father process pid = %d \n",getpid());pid = fork();if(pid > 0){wait(&status);printf("status = %d\n",status);while(1){printf("this is father;pid = %d\n",getpid());sleep(2);printf("father: %d \n",cnt);}}else if(pid == 0){while(1){cnt ++;printf("this is son; pid = %d\n",getpid());sleep(2);if(cnt >= 3){printf("the son exit\n");exit(1);}}}return 0;
}

运行结果如下:

befor fork
father process pid = 7374 
this is son; pid = 7375
this is son; pid = 7375
this is son; pid = 7375
the son exit
status = 65280
this is father;pid = 7374
father: 0 
this is father;pid = 7374
^C

通过运行结果我们可以看到,用wait同样也可以使子线程优先运行。但是,接受到的status不是我们以为的值。那是因为,我们如果想要的是放回的值,那么我们还需要添加那些用于解释进程退出状态的宏。

我们将WEXITSTATU(status)代替status,我们就能得到正常的输出了。

在这里插入图片描述

waitpid函数

waitpid函数,返回值为整型,调用更加灵活,用于等待指定的进程。

status参数是个整形的指针用于存放子进程的结束状态。

pid参数是个整型参数,pid用于指定所等待的进程。

options参数指定所作的操作,取值0:表示进程挂起等待结束;取值WNOHANG表示不使进程挂起而即刻返回;取值WUNTRACED表示进程已经结束并返回。

调用成功返回等待状态的ID;调用失败返回-1。

我们魔改一下wait的代码,使用waitpid代替wait。代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;int cnt = 0;int status;printf("befor fork\n");printf("father process pid = %d \n",getpid());pid = fork();if(pid > 0){waitpid(pid,&status,0);printf("status = %d\n",WEXITSTATUS(status));while(1){printf("this is father;pid = %d\n",getpid());sleep(2);printf("father: %d \n",cnt);}}else if(pid == 0){while(1){cnt ++;printf("this is son; pid = %d\n",getpid());sleep(2);if(cnt >= 3){printf("the son exit\n");exit(37);}}}return 0;
}

运行结果:

befor fork
father process pid = 7530 
this is son; pid = 7531
this is son; pid = 7531
this is son; pid = 7531
the son exit
status = 37
this is father;pid = 7530
^C

通过运行结果,我们可以看到,用waitpid实现了wait函数同样的效果。


system函数

在linux环境下,我们使用man system看到system函数的信息如下:

#include <stdlib.h>int system(const char *command);

我们可以在linux环境中使用system函数执行系统指令。command是一个字符串指针,指向表示命令的字符串。system函数可以执行系统命令,同时也可以调用fork、exec、waitpid。

接下来我们试一试:

#include <stdio.h>
#include <stdlib.h>int main()
{printf("show ls -a \n");system("ls -a");printf("done\n");exit(0);return 0;
}

结果如下:

show ls -a 
.  ..  01fork.c  02fork.c  03vfork.c  04wait.c	05waitpid.c  06system.c  a.out
done

结果与ls -a 效果相同。


总结

进程的相关操作是Linux编程的重要环节。熟悉这些进程控制的api的使用,对我们初学Linux平台下的c语言编程大有帮助。本文重点介绍了,进程的创建常用的俩函数,以及进程的等待。以及system函数。之后将重点介绍一下exec族。

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

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

相关文章

Linux下nginx环境的搭建

1.Nginx的下载 nginx官网&#xff1a;nginx: download nginx的工作原理请移步&#xff1a; 2.nginx安装 2.1.上传文件 将nginx包上传到 /usr/local/src 下 如果你没有使用xftp的话&#xff0c;使用 rz -y 命令上传 下载依赖&#xff1a; yum install lrzsz 输入命令 r…

支持图像和视频理解多模态开源大模型:CogVLM2 CogVLM2-Video

CogVLM2和CogVLM2-Video是新一代的开源模型&#xff0c;支持图像和视频理解&#xff0c;具有显著的性能提升。最近发布的更新包括CogVLM2论文的发表、在线演示和对视频理解的支持&#xff0c;能够处理最多1分钟的视频。新模型支持中英文&#xff0c;文本长度可达8K&#xff0c;…

vue中验证码的实现方式

在写登录页的时候有的系统会让你也进行一下验证码绘制&#xff0c;那么验证码如何实现的呢&#xff1f;我在写登录页的时候通过将登录框&#xff0c;验证码分开页面来写&#xff0c;最后将它们变成标签来导入到我的样式页面中&#xff0c;这样写不仅方便&#xff0c;更容易修改…

Java多进程多线程处理文件

Java多进程多线程处理文件 在现代软件开发中&#xff0c;处理大量或大型文件是一个常见挑战。Java提供了多种机制来处理文件&#xff0c;包括单线程和多线程方式。本文将深入探讨如何使用Java中的多进程和多线程技术来提高文件处理的效率和性能。 目录 引言Java中的进程与线程…

网页核心页面设计(第5章)

一、登录页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-widt…

前端成长之路:HTML(2)

HTML中有两个非常重要的标签——表格和表单&#xff0c;在介绍之前需要先了解表格和表单的区别&#xff1a;表格是用于展示数据的&#xff1b;表单是用于提交数据的。本文主要介绍表格。 表格标签 表格主要是用于显示、展示数据的&#xff0c;并非是页面布局。它可以使本来难…

Leecode刷题C语言之骑士拨号器

执行结果:通过 执行用时和内存消耗如下&#xff1a; 代码如下&#xff1a; #define MOD 1000000007int knightDialer(int n) {int moves[10][4] {{4, 6, -1, -1},{6, 8, -1, -1},{7, 9, -1, -1},{4, 8, -1, -1},{3, 9, 0, -1},{-1, -1, -1, -1},{1, 7, 0, -1},{2, 6, -1, -…

HTML颜色-HTML脚本

HTML脚本 js使得HTML页面具有更强的动态和交互性 HTML<script>标签 标签用于定义客户端脚本&#xff0c;比如javascript 可包含脚本语句&#xff0c;也可以通过src属性指向外部的脚本文件 JavaScript最常用于图片操作&#xff0c;表单验证以及动态的内容更新 HTML<n…

【sgUploadImage】自定义组件:基于elementUI的el-upload封装的上传图片、相片组件,适用于上传缩略图、文章封面

sgUploadImage源码 <template><div :class"$options.name"><ul class"uploadImages"><liclass"uploadImage"v-loading"loadings[i]"v-for"(a, i) in uploadImages":key"i"click"click…

Ubuntu 22.04加Windows AD域

说明&#xff1a;   Ubuntu 22.04系统通过realmd&#xff0c;sssd加入到 Active Directory 域&#xff0c;并为域用户配置sudo权限。同时为方便用户使用为Ubuntu系统安装wps与sogou中文输入法。 1. Ubuntu 22.04加入Windows AD域 1.1 首先配置网络&#xff0c;Ubuntu系统能…

视频中的某些片段如何制作GIF表情包?

动态表情包&#xff08;GIF&#xff09;已经成为我们日常沟通中不可或缺的一部分。GIF&#xff08;Graphics Interchange Format&#xff09;&#xff0c;即图形交换格式&#xff0c;是一种支持多帧图像和透明度的位图文件格式。它最初由 CompuServe 公司在 1987 年推出&#x…

JavaWeb学习--cookie和session,实现登录的记住我和验证码功能

目录 &#xff08;一&#xff09;Cookie概述 1.什么叫Cookie 2.Cookie规范 3.Cookie的覆盖 4.cookie的最大存活时间 ​​​​​​&#xff08;Cookie的生命&#xff09; &#xff08;二&#xff09; Cookie的API 1.创建Cookie&#xff1a;new 构造方法 2.保存到客户端浏…

MySQL Binlog 日志监听与 Spring 集成实战

MySQL Binlog 日志监听与 Spring 集成实战 binlog的三种模式 MySQL 的二进制日志&#xff08;binlog&#xff09;有三种常见的格式&#xff1a;Statement 模式、Row 模式和Mixed 模式。每种模式的设计目标不同&#xff0c;适用于不同的场景&#xff0c;以下是它们的详细对比和…

Android上运行OpenCV(Android Studio)

用Android Studio的话&#xff0c;整体来说没什么难的&#xff0c;照着教程来做就好了。 【OpenCV】OpenCV库的安装 - Android与OpenCV系列教程_哔哩哔哩_bilibili 主要就是导入module&#xff0c;然后加入依赖。代码只有几行。 if(OpenCVLoader.initLocal()){Toast.makeText(…

VLDB 2024 | 时间序列(Time Series)论文总结

VLDB 2024于2024年8月26号-8月30号在中国广州举行。 本文总结了VLDB 2024有关时间序列&#xff08;time series data&#xff09;的相关论文&#xff0c;主要包含如有疏漏&#xff0c;欢迎大家补充。 时间序列Topic&#xff1a;预测&#xff0c;分类&#xff0c;异常检测&…

TongWeb7-东方通快速使用手册

TongWeb7-东方通 快速使用手册 文章目录 第1章 TongWeb7 产品介绍 1.1 概述1.2 规范支持 第2章 TongWeb7 安装 2.1 TongWeb7 安装要求 2.1.1 TongWeb7 支持的操作系统2.1.2 系统要求2.1.3 其他 2.2 安装TongWeb72.3TongWeb7 目录结构说明2.4 TongWeb7 的启动和停止 第3章 应用…

xtu oj 1618 素数个数

文章目录 前言代码思路 前言 有点儿难&#xff0c;至少对我来说。去年考试我没写出来。 代码 #include<stdio.h> #include<stdbool.h> #include<stdlib.h>//加 math 那个头文件好像要加这个头文件&#xff0c;我之前编译错误过&#xff0c;血泪教训 #incl…

非文件形式的内存动态函数库调用接口

使用memfd的系统调用接口将动态库加载到proc虚拟文件系统&#xff0c;提供的fd为进程持有的句柄&#xff0c;通过dlopen的path指向此句柄&#xff0c;即可实现非文件系统加载动态链接库。 文章目录 一、memfd_create二、dl_open三、示例参考 一、memfd_create 接口名称int mem…

ElfBoard开源项目|基于百度智能云平台的车牌识别项目

本项目基于百度智能云平台&#xff0c;旨在利用其强大的OCR服务实现车牌号码的自动识别。选择百度智能云的原因是其高效的API接口和稳定的服务质量&#xff0c;能够帮助开发者快速实现车牌识别应用。 本项目使用摄像头捕捉图像后&#xff0c;通过集成百度OCR服务的API&#xf…

【51单片机】程序实验1112.外部中断-定时器中断

主要参考学习资料&#xff1a;B站【普中官方】51单片机手把手教学视频 前置知识&#xff1a;C语言 单片机套装&#xff1a;普中STC51单片机开发板A4标准版套餐7 码字不易&#xff0c;求点赞收藏加关注(•ω•̥) 有问题欢迎评论区讨论~ 目录 程序实验11&12.外部中断-定时器…