Linux系统编程(11)信号量和管道

一、信号量

                信号量-------让线程间有顺序协调地工作,它可以用来协调多个线程或进程,使得它们不会因为同时访问共享资源而导致数据不一致或系统崩溃。

二、信号量的操作

信号量主要有两个基本操作:

  1. 等待(P 操作):表示使用这个资源。

    • 线程或进程尝试获取信号量的资源。
    • 如果信号量的计数器大于 0,则减 1 并继续执行。
    • 如果信号量的计数器等于 0,线程或进程将进入等待状态,直到信号量大于 0。
  2. 释放(V 操作):表示产生这个资源。

    • 线程或进程释放信号量的资源。
    • 信号量的计数器加 1。
    • 如果有等待的线程或进程,则唤醒它们中的一个。

三、信号量的分类

  • 有名信号量(Named Semaphore)

    • 允许不同进程间通过名称共享信号量。
    • 用于进程间同步,可以跨进程访问。
  • 无名信号量(Unnamed Semaphore)

    • 只能在同一个进程或线程组内使用
    • 不需要名称,在创建时直接初始化。

四、信号量的相关函数

sem_t : 数据类型,用来定义信号量

sem_t sem;

        定义了一个数据类型为sem_t 的变量,名为sem; 

sem_init

  • 用于初始化一个无名信号量。
  • 原型:
    int sem_init(sem_t *sem, int pshared, unsigned int value);
  • 参数:
    • sem:指向信号量对象的指针。
    • pshared:为 0 表示信号量用于进程内线程之间的同步;非 0 表示用于进程间同步。
    • value:信号量的初始值。

sem_wait(P操作)

  • 使调用线程阻塞,直到信号量值大于 0。
  • 原型:
    int sem_wait(sem_t *sem);
  • 参数:
    • sem:指向信号量对象的指针。

sem_post:(V操作)

  • 增加信号量的值(释放信号量)。
  • 原型:
    int sem_post(sem_t *sem);
  • 参数:
    • sem:指向信号量对象的指针。

sem_destroy

  • 用于销毁一个无名信号量。
  • 原型:
    int sem_destroy(sem_t *sem);
  • 参数:
    • sem:指向信号量对象的指针。

五、管道

        由于每个进程具有独立的内存空间 ,进程通信实际上都是在内核中才能进行数据的交换

       介绍 IPC (进程间通信)中的古老通信方式:管道

        管道可以看作是一个数据流的通道,其中一个进程将数据写入管道的写端,另一个进程从管道的读端读取数据。

        管道实际上也是在内核中运行的。

   

管道的类型

管道主要分为以下几种类型:

  1. 无名管道(Unnamed Pipe)

  2. 有名管道(Named Pipe)

无名管道的操作方法

1. 创建无名管道

        通过 pipe() 系统调用创建无名管道。pipe() 调用会创建一个包含两个文件描述符的数组:

int fd[2];
pipe(fd);
  • fd[0]:表示管道的读端(读取数据)。
  • fd[1]:表示管道的写端(写入数据)。
  • 创建成功返回0,失败返回-1,并设置errno。
2.无名管道的特点

1.单向通信;

无名管道本质上是单向的,即数据只能从管道的一端流向另一端:

  • 写端(fd[1]):负责向管道写入数据。
  • 读端(fd[0]):负责从管道读取数据。

如果需要双向通信,通常要创建两个无名管道。

2.无名管道的大小:65536byte  64k

        管道中的数据量不能超过这个大小,否则写操作会阻塞。

3.管道操作的四种情况

  • 写端存在,读端也存在

    • 写操作:当写端和读端都存在时,如果管道为空,写端可以持续写入数据,直到管道缓冲区被写满。
    • 读操作:读端在有数据时读取数据,读取后数据会从管道中删除。
  • 写端存在,读端不存在

    • 写操作:如果管道的读端被关闭,但写端继续写入数据,此时写操作会导致管道破裂,并触发 SIGPIPE 信号。该信号通常会导致写入的进程终止,除非该信号被捕获或忽略。
  • 写端不存在,读端存在

    • 读操作:当写端被关闭,读端依然可以读取管道中的数据。如果管道中没有数据,读操作会返回 0,表示 EOF(文件结束)。这表明管道的另一端已经关闭,读操作不会阻塞。
  • 写端存在,读管道

    • 读操作:当管道中还有数据时,读端可以读取这些数据。如果管道中没有数据且写端未关闭,读操作会阻塞,等待新数据的写入。

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值