linux进程和进程通信编程(1)
What makes the desert beautiful is that somewhere it hides a well.
沙漠之所以美丽,是因为在它的某个角落隐藏着一口井.
linux进程和进程通信编程(1)
- 1.什么是进程
- 2.进程id(pid)
- 3.进程间通信的方法
- 管道
- 信号
- IPC
- Socket
- 4.创建进程
- fork
- fork有三个返回值
- 父进程pid为1的原因
- 5.exec函数族
- execl
- 15.c代码
- 6.ps
- 7.kill
- 16.c代码
- 8.孤儿进程
- 17.c代码
- 9.僵尸进程
- 172.c代码
- 10.wait
- 18.c代码
- 11.守护进程
- 如何创建守护进程
- 19.c代码
1.什么是进程
正在运行的程序
进程 : 相当于一个同学
进程组 : 相当于一个班
会话 : 相当于一个年级
进程直接要通过linux内核进行通信

就绪态: 就差cpu
执行态到阻塞态: 因为某件事给卡住了
2.进程id(pid)
每个进程唯一的标识符
3.进程间通信的方法
管道
有名管道, 无名管道
信号
发送, 结束, 处理
IPC
共享内存, 消息队列, 信号灯
Socket
4.创建进程
用一个进程(父进程)去创建另一个进程(子进程)
子进程相当于父进程的拷贝
fork
参考程序14.c
//头文件
#include <sys/types.h>
#include <unistd.h>
fork有三个返回值
在父进程里面,返回子进程pid; 在子 进程里返回0, 出错返回负数
原本这整个程序是父进程, 最开始用了fork, 就生成了一个子进程(看不见的), 父子进程都去完整的执行了这个程序(因为可以看见分别执行了两次i++), 只是父进程只能去输出第一个if, 子进程只能去输出第二个if

父进程pid为1的原因
因为由于父进程先退出了,造成子进程被init(ID=1)接管,所以用getppid出来的是1. 最后在跑父进程的时候加了sleep就能保证父进程后退出。

5.exec函数族
execl
相关程序15.c
用于让父子进程去执行不同的程序(x.sh)或命令(ls)
execl执行之后, 子进程就不会再往后执行了
execl("要执行的文件的绝对路径", "./要执行的文件", 要执行的文件的参数);
1 . 用法
查找要执行的文件的绝对路径, 记得给需要执行的文件加权限

execl("/root/amiao/15.1.sh", "./15.1.sh", NULL);
如果执行成功, j就不返回, 不成功 , j就返回-1

2 . execl执行之后, 子进程就不会再往后执行了
比如这个, 父进程把整个程序执行完了(因为输出了i), 子进程执行了execl之后就没有执行i++了

这个也可以看出来, 把execl移到前面去, a++也不执行了

3 . 放父进程也一样, 不执行a++了

4 . 执行pwd命令
一般系统命令路径就是/bin/xx

15.c代码
// execl#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t#include <unistd.h> //用于close,read,write,forkint main() //不含参数
{int j;int a = 0;int b = 0;pid_t pid; //定义一个pid来接收fork的返回值pid = fork();int i = 0;if (pid < 0){printf("创建失败");}//父进程if (pid > 0){printf("这是父进程,其pid为%d\n", getpid()); // getpid是获得当前进程id}//子进程if (pid == 0){printf("a:%d\n", a);printf("这是子进程,其pid为%d,", getpid()); // getpid是获得当前进程pidprintf("其父进程pid为%d\n", getppid()); // getppid是获得当前进程父进程的pid// j = execl("/root/amiao/15.1.sh", "./15.1.sh", NULL); //运行15.1.sh,要用绝对路径// printf("j:%d\n", j);execl("/bin/pwd", "pwd", NULL);printf("b:%d\n", b);}i++;printf("i:%d\n", i);
}
6.ps
用于列出系统中正在运行的进程的各种信息, 比如pid

查看某一个命令的进程

7.kill
用于杀死进程
相关程序16.c
要一边运行16.c(编译成hell), 一边查pid才行, 不然pid查的是错的

如果是按f9运行的(这里我用的VScode远程连接的kali), 就直接查16(VS把16.c编译成16)

16.c代码
// kill的用法#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t#include <unistd.h> //用于close,read,write,forkint main() //不含参数
{pid_t pid; //定义一个pid来接收fork的返回值pid = fork();if (pid < 0){printf("创建失败");}//子进程if (pid == 0){while (1){printf("这是子进程,其pid为%d,", getpid()); // getpid是获得当前进程pid} }}
8.孤儿进程
参考进程17.c
就是一个没结束的子进程, 但它的父进程已经结束了
这个子进程的ppid为1(有些特殊的系统可能不是1)
比如这个,先运行完父进程,再运行子进程,就得到父进程为1

17.c代码
// 孤儿进程#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t#include <unistd.h> //用于close,read,write,forkint main() //不含参数
{pid_t pid; //定义一个pid来接收fork的返回值pid = fork();if (pid < 0){printf("创建失败");}//父进程if (pid > 0){while (1);printf("这是父进程,其pid为%d\n", getpid()); // getpid是获得当前进程id}//子进程if (pid == 0){// sleep(2); //停2s,让父进程先结束,再运行子进程printf("这是子进程,其pid为%d,", getpid()); // getpid是获得当前进程pidprintf("其父进程pid为%d\n", getppid()); // getppid是获得当前进程父进程的pid}}
9.僵尸进程
参考进程172.c
是一个没有被释放进程块的子进程
父进程没结束, 子进程结束了, 但是父进程不去释放这个进程控制块

kill父进程

172.c代码
// 僵尸进程#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t#include <unistd.h> //用于close,read,write,forkint main() //不含参数
{pid_t pid; //定义一个pid来接收fork的返回值pid = fork();if (pid < 0){printf("创建失败");}//父进程if (pid > 0){while (1);}//子进程if (pid == 0){// sleep(2); //停2s,让父进程先结束,再运行子进程printf("这是子进程,其pid为%d,", getpid()); // getpid是获得当前进程pidprintf("其父进程pid为%d\n", getppid()); // getppid是获得当前进程父进程的pid}}
10.wait
用于减少僵尸进程产生
当父进程调用了wait, 就会直接阻塞父进程, 然后去把父进程的子进程结束之后的空间给释放了
参考程序18.c
//头文件
#include <wait.h>

18.c代码
//wait,用于减少僵尸进程产生,当父进程调用了wait, 就会直接阻塞父进程, 然后去把父进程的子进程结束之后的空间给释放了#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t#include <unistd.h> //用于close,read,write,fork
#include <wait.h> //用于waitintmain() //不含参数
{pid_t pid; //定义一个pid来接收fork的返回值pid = fork();if (pid < 0){printf("创建失败");}//父进程if (pid > 0){sleep(2); //停2s,让子进程先结束,再运行父进程int status;wait(&status);if (WIFEXITED(status) == 1) // WIFEXITED(status)==1表示子进程是正常运行完退出的,不是被kill的{ printf("子进程结束的返回:%d\n" ,WEXITSTATUS(status));//返回子进程中的exit里面的数}}//子进程if (pid == 0){printf("这是子进程,其pid为%d,", getpid()); // getpid是获得当前进程pidprintf("其父进程pid为%d\n", getppid()); // getppid是获得当前进程父进程的pidexit(6);}
}
11.守护进程
就是后台进程, 与所有终端没有关联, 不能和用户交互, 不能ctrl+c退出
参考程序19.c
如何创建守护进程
其中1 ,2 ,6 是必须的
1 . 必须是init(pid=1的那个) 的子进程
用fork创建一个子进程, 然后让父进程用exit退出, 然后这个子进程就是init的子进程了
2 . 不跟终端交互
用setsid函数创建一个新会话, 会话里面的首进程不和终端交互
3 . 用chdir , 将当前目录改成根目录
因为有时候会把程序写在U盘里, U盘拔了 , 就不能在系统里面运行了, chdir用于避免这种情况
4 . 重设umask文件掩码
父进程和子进程掩码是一样的, 如果不想要一样的, 就用umask改了
5 . 关闭文件描述符
用于节约资源
6 . 执行代码
该输出的还是会输出,只是重启时会开机自启

19.c代码
// 守护进程#include <stdio.h> //用于main函数
#include <stdlib.h>
#include <sys/types.h> //用于pid_t
#include <sys/stat.h>#include <unistd.h> //用于close,read,write,fork
int main() //不含参数
{pid_t pid; //定义一个pid来接收fork的返回值pid = fork();if (pid < 0){printf("创建失败");}//父进程if (pid > 0){exit(0); //让父进程直接退了}//子进程if (pid == 0){setsid(); //用setsid函数创建一个新会话,不跟终端交互chdir("/"); //将当前目录改成根目录umask(0); //重设umask文件掩码close(0); //关闭文件描述符while (1) //用while循环写出一直要执行的代码{printf("hh");printf("其父进程pid为%d\n", getppid());}}
}










相关文章:
linux进程和进程通信编程(1)
What makes the desert beautiful is that somewhere it hides a well. 沙漠之所以美丽,是因为在它的某个角落隐藏着一口井. linux进程和进程通信编程(1)1.什么是进程2.进程id(pid)3.进程间通信的方法管道信号IPCSocket4.创建进程forkfork有三个返回值父…...
操作系统(1.3)--习题
一、课堂习题 1、一个作业第一 次执行时用了5min ,而第二次执行时用了6min,这说明了操作系统的( )特点。 A、并发性 B、共享性 C、虚拟性 D、不确定性 D 2、在计算机系统中,操作系统是( )。 A、处于裸机之上的第一层软件 B、处于硬件之下的低层软件 C、处于应用软件之上的系统软…...
刷题笔记之十三(有假币、最难的问题、因子个数)
目录 1. 求正数数组的最小不可组成和 2. 有假币 3. 继承时先调用父类的构造方法;类中的成员变量的初始化操作都在构造方法时进行 4. 学会并理解装箱拆箱,注意new出来的也可以拆!! 5. getDeclaredMethods()是标识类或接口的声明成员(这个表示public private 包访问权限 pro…...
5个代码技巧,加速你的Python
5个代码技巧,加速你的Python 人生苦短,快学Python! Python作为一种功能强大的编程语言,因其简单易学而受到很多初学者的青睐。它的应用领域又非常广泛:科学计算、游戏开发、爬虫、人工智能、自动化办公、Web应用开发…...
字节跳动软件测试岗,前两面过了,第三面HR天坑!竟然跟我说……
阎王易见,小鬼难缠。我一直相信这个世界上好人居多,但是也没想到自己也会在阴沟里翻船。我感觉自己被字节跳动的HR坑了。在这里,我只想告诫大家,offer一定要拿到自己的手里才是真的,口头offer都是不牢靠的,…...
[数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北
本文主要介绍GeoPandas的基本使用方法,以绘制简单的地图。GeoPandas是一个Python开源项目,旨在提供丰富而简单的地理空间数据处理接口。GeoPandas扩展了Pandas的数据类型,并使用matplotlib进行绘图。GeoPandas官方仓库地址为:GeoP…...
ChatGPT加强版GPT-4面世,打工人的方式将被颠覆
🔗 运行环境:chatGPT,GPT-4 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好&#…...
Python逆向及相关知识
今天第二次看见python字节码的逆向题,然后发现了一个介绍Python逆向的文章,所以把文章里的内容简单整理记录一下。 文章参考:https://www.cnblogs.com/blili/p/11799398.html Python运行原理: 一.什么是Python Python 是一种解…...
Python基础语法、注意点加实例全解
本篇文章我们讲解Python最基础语法,包含:数据类型、注释、变量、类型转换、命名规范、运算符、字符串拼接、字符串格式化、if条件判断、while循环、for循环、函数、读取文件、写入文件、异常捕获、包导入等。通过讲解语法注意事项实例代码详解࿰…...
ETH RPC搭建
配置选择先是看了aws、谷歌云、阿里云这个配置都要1-2wrmb一个月,太贵了问了很多朋友,打算用hetzner,50欧一个月足以我选的配置:64gb,2tb ssd开好后在邮箱收到信息链接后按以下步骤安装系统:https://0o0.me…...
南京邮电大学数据库第一次课后作业
1.单选题 (5分) (B)是存储在计算机内有结构的数据的集合。 (A)数据库系统 (B)数据库 (C)数据库管理系统 (D)数据结构 2.单选题 (5分) 数据库的特点之一是数据的共享,严格的讲,这里的…...
近期投简历、找日常实习的一些碎碎念(大二---测试岗)
嘿嘿嘿,我又回来了,相信不少兄弟已经发现我似乎已经断更了好久,哈哈,我是尝试去找实习,投简历面试去了。 先说一下背景。 目录 背景 求职进行中 简历 投递和沟通 收获和感受 背景 博主,大二软件工程…...
ThreadLocal的使用
1. ThreadLocal介绍 ThreadLocal顾名思义,就是线程的本地变量,只有当前线程可见,对其他线程来说是封闭且隔离的。每一个线程为自己本身创建ThreadLocal变量,只有当前线程可以访问,其他的线程不可以,从根源…...
Java ~ Reference【总结】
一 概述 简介 在JDK1.2之前,Java中引用的定义是十分传统的:如果引用类型的变量中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。在这种定义之下,一个对象只有被引用和没有被引用两种状态。 实际上…...
最快方法求最长上升子序列(LIS)+最长公共子序列(LCS)模板(C/C++)
目录 1 LIS算法(最长上升子序列) 1.1 简介 1.2 代码 1.3 相关解释 2 LCS算法(最长公共子序列) 2.1 简介 2.2 代码(动态规划,时间复杂度O(nlogn)) 2.3 特殊…...
012+limou+C语言深入知识——(4)“结构体”与“枚举体”与“联合体”
一、结构体 1、结构体基础 (1)结构体完全声明 struct tag {member-list; }variable-list;//描述一个人 struct people {char name[10];//人名int age;//年龄int idnumber;//身份证 };(2)结构体不完全声明(匿名结构体…...
Canvas百战成神-圆(1)
Canvas百战成神-圆 初始化容器 <canvas id"canvas"></canvas>canvas{border: 1px solid black; }让页面占满屏幕 *{margin: 0;padding: 0; } html,body{width: 100%;height: 100%;overflow: hidden; } ::-webkit-scrollbar{display: none; }初始化画笔…...
详解分库分表设计
详解分库分表设计 背景 在传统的单机数据库架构中,所有数据都存储在同一个数据库中,随着业务规模的不断扩大,数据量和并发量也会越来越大,这会给数据库的性能和可用性带来挑战。此外,当单机数据库的容量达到瓶颈时…...
动态规划-基础(斐波那契数、爬楼梯、使用最小花费爬楼梯、不同路径、不同路径II、整数拆分、不同的二叉搜索树)
动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的。动态规划问题,五步走:状态定义&am…...
深入理解WebSocket协议
“ 一直以来对WebSocket仅停留在使用阶段,也没有深入理解其背后的原理。当看到 x x x was not upgraded to websocket,我是彻底蒙了,等我镇定下来,打开百度输入这行报错信息,随即看到的就是大家说的跨域,或…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
