【Linux】进程间通信 -- 信号量

这篇具有很好参考价值的文章主要介绍了【Linux】进程间通信 -- 信号量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概念引入

信号量是什么?
本质是一个计数器,通常用来表示公共资源中,资源数量多少的问题

公共资源:能被多个进程同时可以访问的资源

访问没有保护的公共资源:数据不一致问题(比如我想写abc123,但是我123还没有写入,就读取了abc,可能数据分开会导致数据无意义)

为什么要让不同的进程看到同一份资源呢?

因为我想通信,进程间实现协同。但是进程具有独立性,没有办法让两个进程直接通信,为了解决这种问题,解决办法就是让进程看到同一份资源,但是因为提出了这个方法,同时也引入了新的问题:数据不一致

我们将保护起来的公共资源称为:临界资源(大部分资源是独立的)

资源包括内存、文件、网络等,资源存在的意义就是要被使用,如何被进程使用呢?
一定是该进程有对应的代码来访问这部分临界资源(有临界区就有非临界区)

多进程在进行进程间通信时本质是要看到一份公共的资源,这部分公共资源在未来如果被保护起来,那么这部分公共资源我们就称其为临界资源,而访问该临界资源中我们自己的那部分代码我们叫做临界区,不访问临界资源那部分代码的我们叫做非临界区

如何保护资源:互斥与同步
原子性:要么不做,要做就做完,只有两种状态(不会被线程调度机制打断的操作)

为什么要信号量?

举例认识:比如我们看电影,我们不是只要坐在一个座位上,那么这个座位就属于你了,而是你要去买票,然后给你分配一个座位,这个座位才属于你,不管你去不去,你只要买票了,那么这个座位始终都会留给你,这种电影买票的本质:对放映厅中的座位进行预定机制。我们想要某种资源的时候也可以进行预定。

共享资源的使用:作为一个整体使用、划分为一个一个的子资源使用
我们想让不同的进程同时访问一份资源的不同区域,这样我们某种程度上能实现并发

假如我们将一份共享资源(电影院)分成几份,进程(人),访问共享资源的子部分(电影的座位),我们不能直接去访问这些资源(不能不买票随便坐),信号量(电影票),每个进程先申请信号量,如果申请成功了,就相当于预定这部分资源(买到票有座位),申请失败就不允许访问这部分资源(没买票到不允许看电影)。这种申请信号量方式以达到保护共享资源,约束其他进程的目的。信号量就是计数器(电影票是有限的),申请一个就少一个。

sem = 20;//定义信号量总数

sem--;  //预定资源

//访问公共资源

sem++;  //释放资源

PV操作:P → 预定资源 V → 释放资源

所有的进程在访问公共资源之前,都必须先申请sem信号量→必须先申请sem信号量的前提,是所有进程必须先得看到同一个信号量→信号量本身就是公共资源→信号量是不是也要保证自己的安全呢?- -,++→信号量必须保证自身操作的安全性,- -,++操作是原子! !

如果一个信号量初始值为1:二元信号量–互斥功能

思考:有没有可能两个进程都申请信号量成功了却访问同一个资源?
有的,申请信号量成功只能表明这个资源一定有部分是留给你访问的,但具体是哪一部分还需要确认。这部分的工作一般是由程序员来指定的


信号量操作接口

1.申请信号量semget

【Linux】进程间通信 -- 信号量,Linux基础,linux,服务器,运维,进程间通信,信号量
函数原型:

int semget(key_t key, int nsems, int semflg);

函数参数:

  1. key:一个用于标识信号量集的键值,它必须是一个非零的整数。通常使用 ftok 函数来生成键值。
  2. nsems:信号量集中包含的信号量的数量。这个参数必须是一个大于零的整数。
  3. semflg:一个标志参数,用于指定信号量集的创建和访问权限。常见的标志包括:
    IPC_CREAT:如果指定的 key 值对应的信号量集不存在,则创建它。
    IPC_EXCL:如果同时指定了 IPC_CREAT 和 IPC_EXCL 标志,而对应的信号量集已经存在,则会出现错误。
    0666:指定新创建的信号量集的权限。这个参数使用八进制表示,表示该信号量集可以被所有用户读写。

函数返回值:
semget 函数的返回值是一个信号量集的标识符,也称为“信号量集描述符”。它是一个非负整数,可以用于后续的信号量操作函数中。

2.控制信号量semctl

【Linux】进程间通信 -- 信号量,Linux基础,linux,服务器,运维,进程间通信,信号量
函数原型:

int semctl(int semid, int semnum, int cmd, ...);

函数参数:

  1. semid:一个信号量集的标识符,它是由 semget 函数返回的。

  2. semnum:要操作的信号量在信号量集中的编号,从 0 开始计数。

  3. cmd:用于指定要执行的操作,常见的操作包括:
    GETVAL:获取指定信号量的当前值。
    SETVAL:设置指定信号量的值。
    IPC_RMID:删除指定的信号量集。
    IPC_STAT:获取指定信号量集的状态信息。
    IPC_SET:设置指定信号量集的状态信息。

  4. ... :可选参数,用于给 SETVAL 命令指定要设置的值。

函数返回值根据不同的命令而异:

  • 对于 GETVAL 命令,返回指定信号量的当前值。
  • 对于 SETVAL 命令,返回 0 表示操作成功,-1 表示操作失败。
  • 对于 IPC_RMID、IPC_STAT 和 IPC_SET 命令,返回 0 表示操作成功,-1 表示操作失败。

3.处理信号量semop

【Linux】进程间通信 -- 信号量,Linux基础,linux,服务器,运维,进程间通信,信号量

int semop(int semid, struct sembuf *sops, unsigned nsops);

函数参数:

  1. semid:一个信号量集的标识符,它是由 semget 函数返回的。
  2. sops:一个指向 sembuf 结构体数组的指针,每个结构体描述一个操作。sembuf 结构体定义如下:
struct sembuf {
    unsigned short sem_num;  // 操作的信号量在信号量集中的编号
    short sem_op;            // 操作的值
    short sem_flg;           // 操作的标志
};
- `sem_num`:要操作的信号量在信号量集中的编号,从 0 开始计数。

- `sem_op`:要执行的操作,可以是一个正数、负数或零。

  - 如果 `sem_op` 是一个正数,表示对应的信号量的值将增加 `sem_op`。

  - 如果 `sem_op` 是一个负数,表示对应的信号量的值将减少 `sem_op`。

  - 如果 `sem_op` 是零,表示对应的信号量的值不变。

- `sem_flg`:操作的标志,包括:

  - `SEM_UNDO`:表示在进程异常终止时,内核将撤销该进程所做的所有操作。

  - `IPC_NOWAIT`:表示如果无法立即执行相应的操作,则立即返回。
  1. nsops:sops 数组中元素的数量。

函数返回值:
表示是否操作成功,如果成功则返回 0,如果失败则返回 -1。

IPC资源的组织方式

共享内存、消息队列、信号量它们的接口相似度很高,比如获取与删除

且它们开始都是定义:

struct ipc_perm {
    key_t          __key;    /* Key supplied to shmget(2) */
    uid_t          uid;      /* Effective UID of owner */
    gid_t          gid;      /* Effective GID of owner */
    uid_t          cuid;     /* Effective UID of creator */
    gid_t          cgid;     /* Effective GID of creator */
    unsigned short mode;     /* Permissions + SHM_DEST and
                                SHM_LOCKED flags */
    unsigned short __seq;    /* Sequence number */
};

【Linux】进程间通信 -- 信号量,Linux基础,linux,服务器,运维,进程间通信,信号量
对其进行操作:

(struct shmid_ds*)perms[0]->其他的属性

struct shmid_di myshm;
perms[0] = &myshm.shm_perm;

struct msqid_ds mymsg;
perms[1] = &mymsg.msg_perm;

结构体的第一个成员的地址,在数字上和结构体对象本身的地址数字是相等的,我们就可以通过结构体的地址,强转struct shmid_ds*来使用其里面的其他属性,如上述伪代码。


如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀文章来源地址https://www.toymoban.com/news/detail-597950.html

到了这里,关于【Linux】进程间通信 -- 信号量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】进程间通信之共享内存/消息队列/信号量

    共享内存是通过让不同的进程看到同一个内存块的方式。 我们知道,每一个进程都会有对应的PCB-task_struct ,独立的进程地址空间,然后通过页表将地址映射到物理内存中。此时我们就可以让OS在内存中申请一块空间,然后将创建好的内存空间映射到进程的地址空间中,两个需

    2024年02月05日
    浏览(40)
  • 【Linux】进程间通信——system V共享内存 | 消息队列 | 信号量

    共享内存是一种在多个进程之间进行进程间通信的机制。它允许多个进程访问相同的物理内存区域,从而实现高效的数据交换和通信。 因为 进程具有独立性(隔离性) ,内核数据结构包括对应的代码、数据与页表都是独立的。OS系统为了让进程间进行通信,必须让不同的进

    2024年02月15日
    浏览(41)
  • Linux之进程间通信——system V(共享内存、消息队列、信号量等)

    本文介绍了另一种进程间通信——system V,主要介绍了共享内存,消息队列、信号量,当然消息队列了信号量并非重点,简单了解即可。 共享内存 :不同的进程为了进行通信看到的同一个内存块,该内存块被称为共享内存。 进程具有独立性,它的内核数据结构包括对应的代

    2024年02月08日
    浏览(46)
  • 【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念

             访问资源在安全的前提下,具有一定的顺序性,就叫做同步 。在多道程序系统中,由于资源有限,进程或线程之间可能产生冲突。同步机制就是为了解决这些冲突,保证进程或线程之间能够按照既定的顺序访问共享资源。同步机制有助于避免竞态条件和死锁(

    2024年04月25日
    浏览(26)
  • 【linux】进行间通信——共享内存+消息队列+信号量

    进程间通信方式目前我们已经学了匿名管道,命名管道。让两个独立的进程通信,前提是看到同一份资源。匿名管道适用于血缘关系的进程,一个打开写端一个打开读端实现的。命名管道适用于完全独立的进程,打开同一份文件实现的。 接下来我们看看剩下的实现进程间通信

    2024年02月05日
    浏览(35)
  • 【C++】Windows下共享内存加信号量实现进程间同步通信

    目录 一,函数清单 1.CreateFileMapping 方法 2.OpenFileMapping 方法 3.MapViewOfFile 方法 4.UnmapViewOfFile 方法 5.CreateSemaphore 方法 6. OpenSemaphore 方法 7.WaitForSingleObject 方法 8.ReleaseSemaphore 方法 9.CloseHandle 方法 10.GetLastError 方法 二,单共享内存单信号量-进程间单向通信 共享内存管理文

    2024年02月08日
    浏览(30)
  • linux(信号量)

    1.回顾信号量的概念 2.认识信号量对应的操作函数 3.认识一个环形队列 4.结合sem+环形队列写生产者消费者模型 --------------------------------------------------------------------------------------------------------------------------------- 1.回顾信号量的概念  每个人想进放映厅看电影,第一件事就是买票

    2024年02月11日
    浏览(30)
  • linux信号量

    通过学习linux的信号量,对linux的信号量进行了编程。

    2024年02月10日
    浏览(32)
  • 【Linux】浅谈信号量

    tips:system V 是一套标准,共享内存,信号量,消息队列属于system V。 进程A和进程B进行通信时,假如进程A向物理内存的共享区写入\\\"Hello World\\\",但是当进程A写入了\\\"Hello\\\"时,进程B就向内存读取了,所以只读取到了\\\"Hello\\\",这就导致进程A想向进程B发送的信息,进程B读取不完整,

    2024年02月05日
    浏览(35)
  • 【Linux从入门到精通】信号量(信号量的原理与相关操作接口)详解

      本篇文章重点对 信号量的概念,信号量的申请、初始化、释放、销毁等操作进行讲解。同时举例把信号量应用到生产者消费者模型来理解 。希望本篇文章会对你有所帮助。 目录 一、信号量概念 1、1 什么是信号量 1、2 为什么要有信号量 1、3 信号量的PV操作 二、信号量的相

    2024年02月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包