Linux 多进程编程详解
Linux 多进程编程详解
多进程编程是现代操作系统中一种重要的并发编程技术。通过在同一程序中运行多个独立的进程,可以实现并发处理,充分利用多核处理器的优势,提高程序的运行效率。本文将详细介绍Linux多进程的基本概念、创建方法、进程间通信、同步机制以及实际应用,配以C++示例代码,帮助读者深入理解和掌握多进程编程技术。
1. 多进程的基本概念
在Linux操作系统中,进程是程序的一个实例,是系统进行资源分配和调度的基本单位。每个进程都有独立的地址空间和资源,包括代码段、数据段、堆、栈以及文件描述符等。进程之间通过进程间通信(IPC)机制进行通信和同步。多进程编程就是在同一程序中创建并运行多个进程,以实现并发处理。
1.1 进程的生命周期
进程的生命周期包括以下几个状态:
创建(New):进程被创建,但尚未准备好执行。
就绪(Ready):进程已准备好执行,但尚未被分配CPU时间。
运行(Running):进程正在执行。
阻塞(Blocked):进程正在等待某些事件(如I/O操作)发生。
终止(Terminated):进程已完成执行或被终止。
进程的状态转换如下图所示:
+-------------------+| 创建 (New) |+-------------------+|v+-------------------+| 就绪 (Ready) |+-------------------+|v+-------------------+| 运行 (Running)|+-------------------+|v+-------------------+| 阻塞 (Blocked) |+-------------------+|v+-------------------+| 终止 (Terminated)|+-------------------+
进程由操作系统调度,从创建到就绪,再从就绪状态转移到运行状态。如果进程在运行过程中需要等待某些事件(如I/O操作),则会进入阻塞状态。当等待的事件发生时,进程重新进入就绪状态,等待调度运行。当进程完成任务或被终止时,进入终止状态。
1.2 进程控制块(PCB)
进程控制块(PCB,Process Control Block)是操作系统管理进程的主要数据结构,包含了进程的各种信息,包括:
进程标识符(PID):每个进程都有一个唯一的标识符。
进程状态:表示进程当前的状态(创建、就绪、运行、阻塞、终止)。
程序计数器(PC):保存进程下一条将要执行的指令地址。
寄存器:保存进程的上下文信息。
内存管理信息:包括进程的地址空间、页表等信息。
I/O状态信息:包括打开的文件描述符、I/O设备等信息。
PCB是操作系统进行进程切换和调度的重要依据。
2. 进程的创建
在Linux中,可以通过fork()系统调用创建一个新的进程。fork()会创建一个子进程,该子进程是父进程的副本,继承了父进程的所有资源和上下文。子进程有自己独立的地址空间,父子进程可以并发运行。
2.1 fork()系统调用
fork()系统调用的原型如下:
pid_t fork(void);
fork()返回两次,一次在父进程中返回子进程的PID,一次在子进程中返回0。如果fork()失败,则返回-1:
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>int main() {pid_t pid = fork(); // 创建一个子进程if (pid < 0) {// fork失败std::cerr << "Fork failed!" << std::endl;return 1;} else if (pid == 0) {// 子进程std::cout << "Hello from Child Process!" << std::endl;std::cout << "Child Process ID: " << getpid() << std::endl;std::cout << "Parent Process ID: " << getppid() << std::endl;} else {// 父进程std::cout << "Hello from Parent Process!" << std::endl;std::cout << "Parent Process ID: " << getpid() << std::endl;std::cout << "Child Process ID: " << pid << std::endl;// 等待子进程结束int status;waitpid(pid, &status, 0);if (WIFEXITED(status)) {std::cout << "Child process exited with status: " << WEXITSTATUS(status) << std::endl;}}return 0;
}
在上述代码中,fork()创建了一个子进程。父进程和子进程分别打印各自的PID和相关信息,并通过waitpid()等待子进程结束。
2.2 进程的终止
进程在完成任务后会终止,终止进程可以通过exit()系统调用实现。exit()系统调用的原型如下:
void exit(int status);
其中,status是进程的退出状态码,通常为0表示正常退出,非0表示异常退出。
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <cstdlib>int main() {pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;} else if (pid == 0) {// 子进程std::cout << "Hello from Child Process!" << std::endl;std::cout << "Child Process ID: " << getpid() << std::endl;std::cout << "Parent Process ID: " << getppid() << std::endl;exit(0); // 子进程正常退出} else {// 父进程std::cout << "Hello from Parent Process!" << std::endl;std::cout << "Parent Process ID: " << getpid() << std::endl;std::cout << "Child Process ID: " << pid << std::endl;// 等待子进程结束int status;waitpid(pid, &status, 0);if (WIFEXITED(status)) {std::cout << "Child process exited with status: " << WEXITSTATUS(status) << std::endl;}}return 0;
}
3. 进程间通信
进程间通信(IPC)是多进程编程中的重要部分,用于在独立的进程之间传递数据和信息。常见的IPC机制包括管道、消息队列、共享内存和信号等。
3.1 管道(Pipe)
管道是一种半双工的通信机制,只能在父子进程或兄弟进程之间使用。管道由两个文件描述符组成,一个用于读端,一个用于写端。使用pipe()系统调用创建管道。
#include <iostream>
#include <unistd.h>
#include <cstring>int main() {int fd[2];if (pipe(fd) == -1) {std::cerr << "Pipe failed!" << std::endl;return 1;}pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;} else if (pid == 0) {// 子进程close(fd[0]); // 关闭读端const char* msg = "Hello from Child Process!";write(fd[1], msg, strlen(msg) + 1); // 写入管道close(fd[1]); // 关闭写端} else {// 父进程close(fd[1]); // 关闭写端char buffer[100];read(fd[0], buffer, sizeof(buffer)); // 从管道读取std::cout << "Parent Process received: " << buffer << std::endl;close(fd[0]); // 关闭读端}return 0;
}
在上述代码中,父子进程通过管道实现通信。子进程将消息写入管道,父进程从管道读取消息。
3.2 消息队列(Message Queue)
消息队列是一种消息传递机制,允许进程以消息的形式进行通信。消息队列是一个链表,每个消息包含一个消息类型和消息数据。使用msgget()、msgsnd()和msgrcv()系统调用管理消息队列。
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <cstring>struct message {long msg_type;char msg_text[100];
};int main() {key_t key = ftok("progfile", 65); // 生成唯一键int msgid = msgget(key, 0666 | IPC_CREAT); // 创建消息队列message msg;msg.msg_type = 1;strcpy(msg.msg_text, "Hello from Child Process!");pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;} else if (pid == 0) {// 子进程,发送消息msgsnd(msgid, &msg, sizeof(msg.msg_text), 0);std::cout << "Message sent from Child Process." << std::endl;} else {// 父进程,接收消息msgrcv(msgid, &msg, sizeof(msg.msg_text), 1, 0);std::cout << "Parent Process received: " << msg.msg_text << std::endl;// 删除消息队列msgctl(msgid, IPC_RMID, NULL);}return 0;
}
在上述代码中,父子进程通过消息队列实现通信。子进程发送消息,父进程接收消息。
共享内存(Shared Memory)
共享内存是一种高效的进程间通信机制,允许多个进程共享一块内存区域。使用 shmget()、shmat() 和 shmdt() 系统调用管理共享内存。
共享内存是所有 IPC 机制中最快的一种,因为进程可以直接访问内存中的数据,而不需要通过内核中介。但是,这也意味着需要额外的同步机制来确保多个进程不会同时修改共享数据而导致数据不一致。
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <cstring>int main() {key_t key = ftok("shmfile", 65); // 生成唯一键int shmid = shmget(key, 1024, 0666 | IPC_CREAT); // 创建共享内存pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;} else if (pid == 0) {// 子进程,写入共享内存char* str = (char*) shmat(shmid
好了,今天的分享到这里就结束了,感谢大家的支持!
相关文章:
Linux 多进程编程详解
Linux 多进程编程详解 多进程编程是现代操作系统中一种重要的并发编程技术。通过在同一程序中运行多个独立的进程,可以实现并发处理,充分利用多核处理器的优势,提高程序的运行效率。本文将详细介绍Linux多进程的基本概念、创建方法、进程间通…...
C语言之大小端理解
目录 1前言2 大小端理解与区分3 大小端的识别和基本切换操作4 总结 1前言 在汽车CAN通讯报文中往往会接触到Intel类型和motorola类型,实际项目中涉及到多机通讯也会接触到大小端问题 2 大小端理解与区分 大端(Big_Endian) :低字节放在高地址小端(Little_Endian):…...
GIT相关操作,推送本地分支到远程仓库流程记录学习
git流程 切换到源文件夹:cd 源文件夹克隆远程仓库:git clone [ssh]进入项目文件夹:cd .\project\查看本地分支:git branch获取远程仓库更新,使远程同步:git fetch查看所有分支(包括远程分支&am…...
网络协议 — Keepalived 高可用方案
目录 文章目录 目录Keepalived 是实现了 VRRP 协议的软件Keepalived 的软件架构VRRP StackCheckersKeepalived 的配置Global configurationvrrp_scriptVRRP Configurationvrrp synchroization groupvrrp instancevirtual ip addressesvirtual routesLVS Configurationvirtual_s…...
前端报错adding CSS “touch-action: none“ to this element解决方案
目录 如图所示控制台出现报错: 原因: touch-action 介绍: 解决方案: 1.手动设置touch-action: 2.使用条件渲染: 3.CSS样式隔离: 4.浏览器兼容性: 5. 忽略警告 如图所示控制台…...
使用phpMyAdmin操作MYSQL(四)
一. 学会phpMyAdmin? phpMyAdminhttp://water.ve-techsz.cn/phpmyadmin/ 虽然我我们可以用命令行操作数据库,但这样难免没有那么直观,方便。所以接下来我们使用phpMyAdmin来操作MySQL,phpMyAdmin是众多MySQL图形化管理工具中使用…...
webpack配置代理请求
在 Webpack 中,可以通过配置devServer中的proxy选项来设置代理请求,以解决开发环境中的跨域问题或实现特定的请求转发逻辑。以下是一个常见的 Webpack 配置示例,展示了如何设置代理: module.exports {// 其他配置项...devServer…...
热门软件缺陷管理工具2024:专业评测与建议
国内外主流的10款软件缺陷管理工具软件对比:PingCode、Worktile、禅道、Tapd、Teambition、Tower、JIRA、Bugzilla、MantisBT、Trac。 在软件开发过程中,管理缺陷和漏洞常常成为一项挑战,尤其是在项目规模庞大时。选择一个高效的软件缺陷管理…...
冒泡,选择,插入,希尔排序
目录 一. 冒泡排序 1. 算法思想 2. 时间复杂度与空间复杂度 3. 代码实现 二. 选择排序 1. 算法思想 2. 时间复杂度与空间复杂度 3. 代码实现 三.插入排序 1. 直接插入排序 (1). 算法思想 (2). 时间复杂度与空间复杂度 (3). 代码实现 2. 希尔排序 (1). 算法思想 …...
【HarmonyOS学习】Calendar Kit日历管理
简介 Calendar Kit提供日历与日程管理能力,包括日历的获取和日程的创建能力。 Calendar Kit为用户提供了一系列接口来获取日历账户,并使用特定的接口向日历账户中写入日程。 如果写入的日程带有提醒时间则系统会在时间到达时向用户发送提醒。 约束点…...
RDMA 高性能架构基本原理与设计方案
RDMA的主要优点包括低延迟、高吞吐量、减少CPU负担和支持零拷贝网络。它允许数据直接在网络接口卡(NIC)和内存之间传输,减少了数据传输过程中的中间环节,从而显著降低了延迟。RDMA技术能够实现高速的数据传输,适用于需…...
【Springboot】事件机制发布与订阅的使用实践
文章目录 为什么要使用事件监听机制概念和原理使用场景用户注册系统实践案例1. 创建事件类2. 发布事件3. 监听事件3.1 通过注解EventListener实现监听3.2 通过实现ApplicationListener接口实现监听 4. 测试事件机制 总结 为什么要使用事件监听机制 在Springboot中,…...
新版网页无插件H.265播放器EasyPlayer.js如何测试demo视频?
H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,支持H.264与H.265编码格式,性能稳定、播放流畅;支持WebSocket-FLV、HTTP-FLV,HLS(m3u8࿰…...
PXE、Kickstart和cobbler
一.系统装机 1.1 三种引导方式 启动操作系统 1.硬盘 2.光驱(u盘) 3.网络启动 pxe 1.2 系统安装过程 1.加载boot loader: Boot Loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设 备、建立内存空间的映射图,从而将系统的软硬…...
【GameFramework扩展应用】6-3、GameFramework框架增加日志保存功能
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录: https://blog.csdn.net/q764424567/article/details/1…...
将独热码应用到神经网络中
引言 接上回,本文继续说如何用TensorFlow将独热编码应用到一个简单的神经网络中,以实现从一段随机文本到另一段随机文本的转换。 步骤一:导入库 import tensorflow as tf import numpy as np import random import string步骤二࿱…...
在CSS中,使用Flexbox布局时,可以通过几个属性来控制容器内的项目之间的间距
display弹性布局,flex:1是占据剩下的空间 关于displa:flex /* 水平和垂直居中,水平和垂直方向上的间距均匀分布 / .container { display: flex; justify-content: space-between; / 左右对齐 / align-items: center; / 上下间距 */ flex-direction: ro…...
关于HDFS 和HBase
Apache HBase 被设计为在 Hadoop 分布式文件系统 (HDFS) 上运行的一个特殊类型的数据库。大白话: 想象一下,你有一个巨大的图书馆,这个图书馆就像 HDFS,它的架子上堆满了各种各样的书籍,每本书都非常厚,而…...
【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法
【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法 众所周知TS是JS的超集,而ArkTs则可以理解为是Ts的超集。他们的基础都基于JS,所以学习之前最好就JS基础。我的学习重点也是放在ArkTs和JS的不同点上。 文章主要跟着官方文档学习,跳过了一…...
Web前端-Web开发CSS基础2-选择器
一. 基础 1. 选中所有的<p>标签; 2. 选中所有的<ol>标签; 3. 选中所有的<ul>标签; 4. 选中所有id为happy的标签; 5. 选中所有id为sad的标签; 6. 选中所有id为angry的标签; 7. 选中所有类…...
人教版高中英语选择性必修四单词音频+单词表+单词默写表(2026年最新)
2026年最新人教版高中英语选择性必修四课本单词表、单词默写表和听力音频,PDF高清电子版,可下载打印!单词音频下载链接:https://pan.quark.cn/s/c757d00cb27d人教版高中英语选修四单词高频30个1、literature /ˈlɪtrətʃə(r)/ …...
Unity WebGL适配微信小游戏全链路指南
1. 为什么Unity WebGL不能直接扔进微信小游戏?——从“能跑”到“能上线”的认知断层很多人第一次尝试把Unity项目导出WebGL再塞进微信小游戏时,都会经历一个相似的困惑:本地浏览器里好好的3D场景,一放进微信开发者工具就白屏、报…...
固始汽车贴膜口碑榜:前3名都有谁?
老铁们,最近固始的车友群里吵翻了,都在问“固始汽车贴膜哪家好”。十个有八个刚提了新车,第一个想到的就是去贴个膜,但这一脚踩下去,水深得很。我直接跟你们说个扎心的事实:固始街头随便找家店,…...
深夜连上服务器,我再也不想敲命令行
前言 那是晚上十一点,我第五次输错IPtables规则,服务器直接失联了。赶紧给机房打电话,求助工程师帮忙重启。电话里听着对方说"下次小心点",我只能苦笑——命令行这东西,真不是熬夜能hold住的。 就在这时&a…...
RK3588 Android系统签名实战:为APK获取系统权限完整指南
1. 项目概述与核心价值在嵌入式Android开发领域,尤其是基于瑞芯微(Rockchip)平台如RK3588进行产品研发时,我们常常会遇到一个核心需求:如何让一个普通的第三方APK应用,获得系统级(System&#x…...
大模型不再“一本正经地胡说八道”!揭秘RAG如何让AI「有据可查」
RAG(Retrieval-Augmented Generation)是一种结合信息检索与文本生成的AI架构,通过让大语言模型在回答问题前先查找外部知识库,有效缓解幻觉问题,并确保答案基于最新、专有数据。RAG通过文档切块、向量嵌入、向量检索和…...
干货合集:2026最新AI论文软件测评与推荐大全
2026年真正好用的AI论文软件,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…...
带标注的螺丝、螺栓、垫圈缺陷识别数据集,包含缺陷里包含生锈和划痕,1291张图,支持yolo,coco json,voc xml,文末有模型训练代码。
带标注的螺丝、螺栓、垫圈缺陷识别数据集,包含缺陷里包含生锈和划痕,1291张图,支持yolo,coco json,voc xml,文末有模型训练代码。 数据集拆分 总图数:1291 张图数 训练集 1143 张图 验证集 106 张图…...
洛圣都生存指南:YimMenu开源游戏增强工具与安全防护系统深度解析
洛圣都生存指南:YimMenu开源游戏增强工具与安全防护系统深度解析 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trendi…...
2026年阿里云OpenClaw/Hermes Agent配置Token Plan部署方法详解
2026年阿里云OpenClaw/Hermes Agent配置Token Plan部署方法详解。OpenClaw是开源的个人AI助手,Hermes Agent则是一个能自我进化的AI智能体框架。阿里云提供计算巢、轻量服务器及无影云电脑三种部署OpenClaw 与 Hermes Agent的方案、百炼Token Plan兼容主流 AI 工具&…...
