进程间的通信(无名管道)

news2024/11/15 7:03:05

进程间通信 IPC

InterProcess Communication

1.进程间通信方式

1.早期的进程间通信:

无名管道(pipe)、有名管道(fifo)、信号(signal)

2.system V PIC:

共享内存(share memory)、信号灯集(semaphore)、消息队列(message queue)

3.BSD:

套接字(socket)

2.无名管道

2.1 特点

  1. 只能用于具有亲缘关系的进程之间的通信
  2. 半双工的通信模式,具有固定的读端fd[0]和写端fd[1]。
  3. 管道可以看成是一种特殊的文件,对于它的读写可以使用文件IO如read、write函数。
  4. 管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符 fd[0]和fd[1]。其中fd[0]固定用于读管道,而fd[1]固定用于写管道。

2.2 函数接口

int pipe(int fd[2])
功能:创建无名管道
参数:文件描述符 fd[0]:读端  fd[1]:写端
返回值:成功 0
       失败 -1

读写特性:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char const *argv[])
{
    char buf[65536] = "";
    int fd[2] = {0}; //fd[0]代表读端,fd[1]代表写端
    if (pipe(fd) < 0)
    {
        perror("pipe err");
        return -1;
    }
    printf("%d %d\n", fd[0], fd[1]);

    //结构类似队列,先进先出
    //1. 当管道中无数据时,读阻塞。
    // read(fd[0], buf, 32);
    // printf("%s\n", buf);

    //但是关闭写端就不一样了
    //当管道中有数据关闭写端可以读出数据,无数据时关闭写端读操作会立即返回。
    // write(fd[1], "hello", 5);
    // close(fd[1]);
    // read(fd[0], buf, 32);
    // printf("%s\n", buf);

    //2. 当管道中写满数据时,写阻塞,管道空间大小为64K
    // write(fd[1], buf, 65536);
    // printf("full!\n");
    //write(fd[1], "a", 1);  //当管道写满时不能再继续写了会阻塞

    //写满一次之后,当管道中至少有4K空间时(也就是读出4K),才可以继续写,否则阻塞。
    // read(fd[0], buf, 4096); //换成4095后面再写就阻塞了,因为不到4K空间
    // write(fd[1], "a", 1);

    //3. 当读端关闭,往管道中写入数据无意义,会造成管道破裂,进程收到内核发送的SIGPIPE信号。
    close(fd[0]);
    write(fd[1], "a", 1);
    printf("read close\n");

    return 0;
}


用gdb调试可以看见管道破裂信号:

gcc -g xx.c

gdb a.out

r

2.3 注意事项

1.当管道中无数据时,读操作会阻塞。

   管道中有数据,将写端关闭,可以将数据读出。

   管道中无数据,将写端关闭,读操作会立即返回。

2.管道中装满(管道大小64K)数据写阻塞,一旦有4k空间,写继续。

3.只有在管道的读端存在时,向管道中写入数据才有意义。否则,会导致管道破裂,向管道中写入数据的进程将收到内核传来的SIGPIPE信号 (通常Broken pipe错误)。

练习题:父子进程实现通信,父进程循环从终端输入数据,子进程循环打印数据,当输入quit结束。

提示:不需要加同步机制, 因为pipe无数据时读会阻塞。

先创建管道再fork,这样父子进程可以使用同一个无名管道。

参考代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char const *argv[])
{
    pid_t pid;
    char buf[32] = "";
    int fd[2];
    if (pipe(fd) < 0)
    {
        perror("pipe err");
        return -1;
    }
    printf("%d %d\n", fd[0], fd[1]);

    pid = fork();
    if (pid < 0)
    {
        perror("fork err");
        return -1;
    }
    else if (pid == 0) //循环打印, quit结束
    {
        while (1)
        {
            read(fd[0], buf, 32); //读出管道中内容存入buf
            if (strcmp(buf, "quit") == 0)
                break;
            printf("%s\n", buf);//将buf内容打印到终端
        }
    }
    else //循环输入,quit结束
    {
        while (1)
        {
            scanf("%s", buf);
            write(fd[1], buf, 32); //把输入buf内容写入管道
            if (strcmp(buf, "quit") == 0)
                break;
        }
        wait(NULL);
    }

    return 0;
}

练习题:请在linux 利用c语言编程实现两个线程按照顺序依次输出”ABABABAB......" 

例如a线程输出”A”之后b线程输出”B”,然后a线程输出“A”,再b线程输出”B”,之后往复循环。

信号量实现(方法一):

#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#include<unistd.h>

char buf[32];
sem_t sem0;
sem_t sem1;

void *handler_thread(void *arg)
{
    while (1)
    {
        //申请资源 sem0
        sem_wait(&sem0); //P操作, -1
        printf("B");
        fflush(NULL);
        //释放资源 sem1
        sem_post(&sem1);
        sleep(1);
    }
}

int main(int argc, char const *argv[])
{
    pthread_t tid;
    if (sem_init(&sem0, 0, 0) != 0)
    {
        perror("sem init 0 err");
        return -1;
    }

    if (sem_init(&sem1, 0, 1) != 0)
    {
        perror("sem init 1 err");
        return -1;
    }

    if (pthread_create(&tid, NULL, handler_thread, NULL) != 0)
    {
        perror("pthread err");
        return -1;
    }

    while (1)
    {
        //申请资源 sem1
        sem_wait(&sem1);
        printf("A");
        fflush(NULL);
        sem_post(&sem0); //V操作,+1
        sleep(1);
    }

    return 0;
}



条件变量实现(方法二):

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t lock;
pthread_cond_t cond;

void *funA(void *arg)
{
    sleep(2);
    while (1)
    {
        sleep(1);
        pthread_mutex_lock(&lock);
        printf("A");
        fflush(NULL);
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&lock);
    }

    pthread_exit(NULL);
}
void *funB(void *arg)
{
    sleep(1);
    while (1)
    {
        pthread_mutex_lock(&lock);
        pthread_cond_wait(&cond, &lock);
        printf("B ");
        fflush(NULL);
        pthread_mutex_unlock(&lock);
    }
    putchar('\n');
    pthread_exit(NULL);
}

int main(int argc, char const *argv[])
{
    pthread_t tid1, tid2;
    pthread_cond_init(&cond, NULL);
    pthread_mutex_init(&lock, NULL);

    if (pthread_create(&tid1, NULL, funA, NULL) < 0)
    {
        perror("tid1 err");
        return -1;
    }
    if (pthread_create(&tid2, NULL, funB, NULL) < 0)
    {
        perror("tid1 err");
        return -1;
    }

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

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

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

相关文章

AI壁纸套装,单月变现7000+,手把手教你,别说你还不会

介绍 这种类型的手机壁纸&#xff0c;平板壁纸&#xff0c;电脑壁纸&#xff0c;甚至是手表壁纸&#xff0c;流量都很不错&#xff0c;尤其是深受一些女性的喜欢。 变现能力也不错&#xff0c;而且变现方式也多种多样。 今天就一步一步的教大家如何制作这种壁纸&#xff0c;怕…

本地部署 Flux.1 最强文生图大模型!Comfyui 一键安装

前言 最近&#xff0c;由前 Stability AI员工创立的黑森林实验室推出了开源文生图大模型–FLUX.1横空出世。 FLUX.1在文字生成、复杂指令遵循和人手生成上具备优势。以下是其生成图像示例&#xff0c;可以看到即使是生成大段的文字、多个人物&#xff0c;也没有出现字符、人手…

涉案财物管理系统|涉案财物全流程监测

涉案财物管理系统DW-S405系统基于物联网技术规范涉案财物管理流程&#xff0c;确保涉案财物的安全性、完整性和合法性&#xff1b;可以提高办案效率&#xff0c;减少办案成本&#xff0c;实现资源共享。 DW-S405可以深度整合大平台和物理存储区的整体一致性&#xff0c;实现对…

通信算法之229: 通信系统中的Eb/N0与SNR

通信系统中接收灵敏度是衡量系统可接收的最小信号电平。各个文章书籍中都给了接收灵敏度与SNR的关系。 但是做解调算法的工程师却在乎的是Eb/No&#xff0c;那么两者的关系什么&#xff1f;是不是都可以代表接收性能的好坏&#xff1f; Eb/No 在通信系统中&#xff0c;Eb/No 是…

带娃赚钱两不误,用AI做故事绘本,零成本轻松变现

01 利用Chatgpt生成故事脚本内容 AI Breakthroug 这一步我们可以将收集的爆款故事文案给到GPT进行改写&#xff0c;这里我重点展示如何通过提示词让GPT帮我们生成原创的故事脚本。 *▍**让GPT生成原创故事标题* 一开始不知道写什么主题故事的时候&#xff0c;这里我们可以…

报错:java: 不再支持源选项 5。请使用 8 或更高版本

Date: 2024.08.30 13:52:20 author: lijianzhan 电脑环境&#xff1a;Windows10 开发环境&#xff1a;JDK21 代码工具&#xff1a;IntelliJ IDEA 2024 一、问题 运行脚本控制台报错&#xff1a;java: 不再支持源选项 5。请使用 8 或更高版本。 二、原因 当前JDK版本比较高&…

【MySQL索引】4索引优化

索引优化 1 关联查询优化 左连接LEFT JOIN LEFT JOIN 右边是我们的关键点,一定需要建立索引 .这里是book的card 字段&#xff0c;type建不建索引无所谓。 ALTER TABLE book ADD INDEX Y ( card); #【被驱动表】&#xff0c;可以避免全表扫描 EXPLAIN SELECT SQL_NO_CACHE *…

2.5G网络(通常指2.5G以太网,即2500BASE-X)的网络变压器在设计和应用上有几个关键方面

信号传输和接收&#xff1a; 2.5G网络变压器主要用于以太网设备中&#xff0c;用于将信号从平衡转换为非平衡&#xff0c;或者进行阻抗匹配&#xff0c;确保信号能够在传输线和接收器之间有效地传输和接收。 频率范围&#xff1a; 这些变压器需要支持2.5G以太网的频率范围&…

Java 入门指南:Java 并发编程 —— 两万字详解 进程(Process)与线程(Thread)

线程和进程是操作系统中两个重要的概念&#xff0c;用于实现并发执行和多任务处理。 基础概念 进程 进程&#xff08;Process&#xff09;&#xff1a;进程是计算机中正在运行的程序的实例。它是操作系统分配系统资源的基本单位&#xff0c;包括程序代码、数据、打开的文件、…

Global Illumination_LPV Deep Optimizations

接上回&#xff0c;RSM优化技术介绍后&#xff0c;我们本部分主要看一下&#xff0c;光栅GI三部曲中的LPV&#xff0c;这个算法算是很巧妙了&#xff0c;算法思路基于RSM上拓展到世界空间&#xff0c;可以说很具学习和思考价值&#xff0c;之前也简单实现过Global Illumination…

【 html+css 绚丽Loading 】000028 九宫幻明轮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

AI智能导诊小程序源码,在智能导诊系统中,自然语言处理技术的运用

概述 智能导诊基于医疗 AI 、自然语言处理技术&#xff0c;推出的在线导医分诊智能工具&#xff0c;覆盖导诊、智能问答、科普宣教等就医服务&#xff1b;智能导诊通过人体图、症状列表等形式进行疾病自测&#xff0c;快速推荐就诊科室、医生推荐。产品可应用于微信线上挂号、…

SQLi-LABS通关攻略【51-55关】

SQLi-LABS 51关 51关和50关一样&#xff0c;只是改为了单引号闭合 依旧有报错信息&#xff0c;可以使用报错注入 构造payload,得到数据库名 ?sort1 and updatexml(1,concat(1,database()),1)-- SQLi-LABS 52关 52关和50关一样&#xff0c;但是没有报错信息&#xff0c;所以报…

智慧监管:地理信息与遥感技术驱动下的社会治理新纪元

在信息化浪潮席卷全球的今天&#xff0c;智慧监管已成为推动社会治理现代化的关键力量。本文将深入剖析智慧监管的概念、技术基础、应用场景及其对社会发展的深远影响&#xff0c;探讨如何在新时代背景下&#xff0c;利用地理信息与遥感技术构建更加智慧、高效的监管体系。 智…

仿华为车机UI--图标从Workspace拖动到Hotseat同时保留图标在原来位置

基于Android13 Launcher3,原生系统如果把图标从Workspace拖动到Hotseat里则Workspace就没有了&#xff0c;需求是执行拖拽动作后&#xff0c;图标同时保留在原位置。 实现效果如下&#xff1a; 实现思路&#xff1a; 1.如果在workspace中拖动&#xff0c;则保留原来“改变图标…

【u盘还原教程】如何把启动u盘恢复回普通U盘

之前制作ubuntu启动盘装双系统 1、插入U盘&#xff0c;右键点击“此电脑”&#xff0c;选择“管理”&#xff0c;在“计算机管理”的面板中点击打开“磁盘管理”&#xff0c;会看到目前电脑上的所有磁盘&#xff0c;找到U盘的索引名&#xff08;如图标识&#xff0c;这里是“…

2024最新VMware17安装Windows10详细记录

本次将带来虚拟机VMware Workstation 17 pro安装Win10的教学&#xff0c;可用于各种软件测试&#xff0c;这里虽然只是示范了win10安装教学&#xff0c;实际上可以安装很多系统&#xff0c;步骤都差不多&#xff1b; 下载 一、下载虚拟机软件 下载方式一&#xff1a;官网下载…

虚拟机安装docker时yum错误及及解决方案

** Could not resolve host: mirrorlist.centos.org; 未知的错误 ** 出现这种错误&#xff0c;先尝试 ping www.baidu.com&#xff0c;然后再尝试 ping mirrorlist.centos.org 如果&#xff0c;baidu.com可以ping通&#xff0c;mirrorlist.centos.org 不能ping通&#xff0…

【三十四】springboot+easyRule初识规则引擎

代码场景&#xff1a;厂里有几个员工&#xff0c;现在厂长颁布了新的厂规关于薪资发放&#xff0c;如下&#xff1a; 1、加班时长超过80小时的&#xff0c;一个小时10块钱&#xff1b;不满80小时的&#xff0c;不算加班。2、上班打卡迟到3次以下的不扣钱&#xff0c;3次以上的一…

期权交易误区分享:喜欢重仓!

今天带你了解期权交易误区分享&#xff1a;喜欢重仓&#xff01;期权交易虽然吸引人&#xff0c;但也有不少容易掉进去的坑。 有的投资者被单个期权的百倍利润吸引&#xff0c;喜欢“一口吃成胖子”。 重仓买入虚值和重度虚值的期权&#xff0c;当标的有大涨或大跌时&#xf…