进程间通信——共享内存,信号量,信号

news2024/12/24 20:24:25

进程 VS 线程通信

进程:共享内存,消息队列,管道,信号(条件变量,锁,信号量需要搭配共享内存使用);
线程:信号,条件变量,锁,信号量

代码示例

使用父子子进程交替打印进行演示

sem_init + 共享内存

重点介绍 sem_init 函数参数
int sem_init(sem_t *sem, int pshared, unsigned int value);
第一个参数sem——信号量地址
第二个参数pshared——0:进程内部通信;非0:进程间通信,必须要配合共享内存一起使用
第三个参数——指定信号量的初始值

#include <iostream>
#include <vector>
using namespace std;
#include <semaphore.h>// 信号量
#include <pthread.h>
#include <sys/ipc.h> // 共享内存
#include <sys/shm.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// 进程间通信 —— 两个进程交替打印
// 1. sem_init + 共享内存
class Text1
{
public:
    struct SemData
    {
        int flag = 0;
        sem_t father;
    };

    const string pathname = "/tmp";
    void Main()
    {
        key_t key = ftok(pathname.c_str(),666);
        int shmid = shmget(key,sizeof(SemData),IPC_CREAT | 0666);// 创建
        if(shmid == -1){
            perror("shmget");
            exit(1);
        }
        cout << shmid << endl;
        SemData* mem = (SemData*)shmat(shmid,nullptr,0);
        if(mem == nullptr){
            perror("shmat");
            exit(2);
        }
        sem_init(&mem->father,1,1);// 进程间共享

        int pid = 0;
        if(pid = fork()){
            // 父进程
            while(1){
                sem_wait(&mem->father);
                printf("father: %d\n",mem->flag++);
                if(waitpid(pid,nullptr,WNOHANG)){
                    break;
                }
                sem_post(&mem->father);
                sleep(1);
            }
            shmdt(mem);
            shmctl(shmid,IPC_RMID,nullptr);
        }else{
            while(1){
                sem_wait(&mem->father);
                if(mem->flag > 10){
                    puts("children exit");
                    sem_post(&mem->father);
                    exit(0);
                }
                printf("children: %d\n",mem->flag++);
                sem_post(&mem->father);
                sleep(1);
                
            }
        }
    }
};
int main()
{
    Text1 test1;
    test1.Main();
    
    return 0;
}

sem_open 进程直接通信

sem_open 参数介绍
sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
第一个参数:以/ 开头的文件路径在测试时发现,就算不加/并且使用不存在的路径也是可以运行的
第二个参数:打开标志——和linux中的文件标志一样
第三个参数:创建的信号量的使用权限,一般使用0666
第四个参数:信号量的数量

#include <iostream>
#include <vector>
using namespace std;
#include <semaphore.h>// 信号量
#include <pthread.h>
#include <sys/ipc.h> // 共享内存
#include <sys/shm.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// sem_open 直接进程间通信
class Text2
{
public:
    void test()
    {
        const string path = "/tmp";
        sem_t* sem_father = sem_open(path.c_str(),O_CREAT | O_EXCL, 0644,1);

        int pid = 0;
        if(pid = fork()){
            // 父进程
            int cnt = 1;
            while(1){
                sem_wait(sem_father);
                printf("father: %d\n",cnt);
                cnt += 2;
                if(waitpid(pid,nullptr,WNOHANG)){
                    break;
                }
                sem_post(sem_father);
                sleep(1);
            }
        }else{
            int cnt = 0;
            while(1){
                sem_wait(sem_father);
                if(cnt > 10){
                    puts("children exit");
                    sem_post(sem_father);
                    exit(0);
                }
                printf("children: %d\n",cnt);
                cnt+=2;
                sem_post(sem_father);
                sleep(1);
            }
        }
    }
    void Main()
    {
        test();
    }
};
int main()
{
    Text2 test2;
    test2.Main();
    
    return 0;
}

在这里插入图片描述

信号通信

注意
SIGUSR1,SIGUSR2 是留给用户自定义行为的信号,我们这里选择SIGUSR1

// 使用信号的方式进行进程间通信
class Text3
{
public:
    // static volatile int flag;
    static volatile int flag;
    static void handle(int sig)
    {
        flag = 1;
    }
    void test()
    {
        signal(SIGUSR1,handle);
        int pid=0;
        if(pid = fork()){
            // 父进程
            while(1){
                while(!flag) {}
                flag=0;
                printf("father\n");
                if(waitpid(pid,nullptr,WNOHANG)){
                    break;
                }
                kill(pid,SIGUSR1);
                sleep(1);
            }
        }else{
            while(1){
                printf("children\n");
                kill(getppid(),SIGUSR1);
                while(!flag){}
                flag=0;

                sleep(1);
            }
        }
    }
    void Main()
    {
        test();
    }
};
volatile int Text3::flag = 0;

int main()
{
    Text3 test3;
    test3.Main();
    
    return 0;
}

在这里插入图片描述

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

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

相关文章

C语言·分支和循环语句(超详细系列·全面总结)

前言&#xff1a;Hello大家好&#x1f618;&#xff0c;我是心跳sy&#xff0c;为了更好地形成一个学习c语言的体系&#xff0c;最近将会更新关于c语言语法基础的知识&#xff0c;今天更新一下分支循环语句的知识点&#xff0c;我们一起来看看吧~ 目录 一、什么是语句&#xf…

C语言航空售票系统

以下是系统部分页面 以下是部分源码&#xff0c;需要源码的私信 #include<stdio.h> #include<stdlib.h> #include<string.h> #define max_user 100 typedef struct ft {char name[50];//名字char start_place[50];//出发地char end_place[50];//目的地char …

【专项刷题】— 归并

1、排序数组 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 先找一个中间值&#xff0c;然后递归左边部分和递归右半部分直到左边和右边只剩一个数了就返回&#xff0c;然后再合并左右两个部分代码&#xff1a; class Solution {int[] tmp;public int[] sortArray(…

canvas:矢量点转栅格

案例描述 ArcGIS提供了“点转栅格”的工具,可以将矢量点转换为栅格数据,以下尝试基于canvas绘图技术,实现经纬度矢量点转换为canvas栅格数据,并在Cesium.js三维地图中进行渲染。 原始数据 转出栅格 案例分析 实现的关键点在于:如何将经纬度坐标与canvas画布坐标进…

Java代码基础算法练习-三角形判断-2024.07.21

任务描述&#xff1a; 解决思路&#xff1a; 一个函数&#xff0c;带入输入的三个边长参数&#xff0c;条件满足计算其周长、面积&#xff0c;否则不计算 代码示例&#xff1a; package a4_2024_07;import java.util.Scanner;public class j240721_2 {public static void mai…

Pytorch学习笔记【B站:小土堆】

文章目录 1 基础环境配置&#xff08;CPU版&#xff09;2 PyTorch学习2.1 Dataset和DataLoader2.1.1 Dataset2.1.2 DataLoader 2.2 Tensorboardadd_scalaradd_imageadd_graph 2.3 Transforms2.3.1 ToTensor2.3.2 Normalize2.3.3 Resize2.3.4 Compose 2.4 torchvision中的数据集…

MQTTX连接华为云IoTDA

目录 华为IoTDA平台 MQTTX连接参数的设置 物模型的构建 属性上报 基本数据格式 时戳 我以前上课都是用巴法云服务器来演示MQTT的&#xff0c;前几天因为测试工业互联网关使用了华为的IoTDA&#xff0c;觉得也不算太复杂&#xff0c;今天尝试用MQTTX连接华为云&#xff0c…

NLP: 词袋模型和TFIDF模型

文章目录 词袋模型TF-IDF模型词汇表模型 词袋模型 文本特征提取有两个非常重要的模型&#xff1a; 词集模型&#xff1a;单词构成的集合&#xff0c;集合自然每个元素都只有一个&#xff0c;也即词集中的每个单词都只有一个。 词袋模型&#xff1a;在词集的基础上如果一个单词…

DDPM扩散模型(模型结构图与公式推导)

DDPM扩散模型 一、前置知识 1. 条件概率知识 P ( A ∣ B ) P ( A B ) P ( B ) P(A|B) \frac{P(AB)}{P(B)} P(A∣B)P(B)P(AB)​ P ( A B C ) P ( C ∣ B A ) P ( B A ) P ( C ∣ B A ) P ( B ∣ A ) P ( A ) P(A B C) P(C|B A)P(BA) P(C|B A)P(B|A)P(A) P(ABC)P(C∣BA)P…

Java | 自制AWT单词猜一猜小游戏(测试版)

目录 游戏标题 开发过程 开发想法 技术栈 代码呈现 导包 核心代码 游戏标题 探索知识的迷宫&#xff0c;体验自制AWT单词猜一猜小游戏 在数字时代&#xff0c;学习可以是多彩的&#xff0c;游戏可以是智慧的。我们自豪地推出“单词猜猜猜”是一款结合了教育与娱乐的自制…

NODEJS复习(ctfshow334-344)

NODEJS复习 web334 下载源码代码审计 发现账号密码 代码逻辑 var findUser function(name, password){ return users.find(function(item){ return name!CTFSHOW && item.username name.toUpperCase() && item.password password; }); }; 名字不等于ctf…

2015年全国大学生数学建模竞赛B题出租车资源配置(含word论文和源代码资源)

文章目录 一、部分题目二、部分论文三、部分源代码问题1问题3 四、完整word版论文和源代码 一、部分题目 2015高教社杯全国大学生数学建模竞赛题目 B题 “互联网”时代的出租车资源配置 出租车是市民出行的重要交通工具之一&#xff0c;“打车难”是人们关注的一个社会热点问…

【CSS in Depth 2 精译_019】3.2 CSS 的盒模型

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

STM32基础篇:USART(下)

双缓冲与连续发送 双缓冲 在发送数据的时候&#xff0c;首先将要发送的字节写入TDR中&#xff0c;然后TDR将此字节发生给移位寄存器&#xff0c;由移位寄存器执行串并转换&#xff0c;通过Tx引脚逐个比特位发送出去。 在此过程中&#xff0c;存在两级缓冲&#xff0c;即双缓…

[GIS实验]居住环境适宜性评价

目的&#xff1a; 拟购买住宅&#xff0c;需在现有条件下&#xff0c;基于地理空间分析方法和空间认知模型对居住环境进行综合评价。通过该实验掌握基于GIS的地理空间认知方法及土地适宜性评价基本原理与方法。 数据&#xff1a; &#xff08;1&#xff09;人口调查图&#…

记录uni-app横屏项目:自定义弹出框

目录 前言&#xff1a; 正文&#xff1a; 前言&#xff1a;横屏的尺寸问题 最近使用了uniapp写了一个横屏的微信小程序和H5的项目&#xff0c;也是本人首次写的横屏项目&#xff0c;多少是有点踩坑不太适应。。。 先说最让我一脸懵的点&#xff0c;尺寸大小&#xff0c;下面一…

探索Python错误美化:pretty_errors库的魔法之旅

探索Python错误美化&#xff1a;pretty_errors库的魔法之旅 背景&#xff1a;为什么需要pretty_errors&#xff1f; 在Python编程中&#xff0c;错误和异常是不可避免的。然而&#xff0c;Python默认的错误信息往往不够直观&#xff0c;对于新手来说可能难以理解。pretty_erro…

MySQL学习之InnoDB引擎,索引

Mysql中的引擎 我们先来看一下MySql提供的有哪些引擎 mysql> show engines; 从上图我们可以查看出 MySQL 当前默认的存储引擎是InnoDB,并且在5.7版本所有的存储引擎中只有 InnoDB 是事务性存储引擎&#xff0c;也就是说只有 InnoDB 支持事务。 查看MySQL当前默认的存储引…

Transformer之Vision Transformer结构解读

论文地址 代码地址 写在前面 什么是Transformer呢&#xff1f;就是把符号向量化为Token&#xff0c; 再和位置编码求和或者做阿达玛积&#xff0c;最后送入一定层数的Attention Block构成的Encoder和Decoder&#xff0c;就完成了Transformer的基础功能。 那么&#xff0c;把上…

关于模的问题

写代码的时候遇到模的问题 class Solution:def countCompleteDayPairs(self, hours: List[int]) -> int:ans 0t [0 for _ in range(24)]for h in hours:u (24-h%24)%24ans t[u]t[h%24] 1return ans如果写成 u (24-h%24) 是不对的&#xff0c;没有考虑h等于0的情况