Linux进程间通信之信号量(semaphore)、消息队列(Message Queue)和共享内存(Share Memory)

System V 进程通信方式:信号量(semaphore)、消息队列(Message Queue)和共享内存(Share Memory)

信号量

信号量(semaphore)实际是一个整数,它的值由多个进程进行测试(test)和设置(set)。就每个进程所关心的测试和设置操作而言,这两个操作是不可中断的,或称”原子”操作,即一旦开始直到两个操作全部完成。测试和设置操作的结果是:信号量的当前值和设置值相加,其和或者是正或者为负。根据测试和设置操作的结果,一个进程可能必须睡眠,直到有另一个进程改变信号量的值。

信号量可用来实现所谓的”临界区”的互斥使用,临界区指同一时刻只能有一个进程执行其中代码的代码段。为了进一步理解信号量的使用,下面我们举例说明。

假设您有许多在数据文件中读取或写入记录的协作进程。您可能希望严格协调对该文件的访问,因此您使用一个初始值为1的信号量,对该信号量执行两个操作,首先测试并从信号量中减去1,然后测试并将1加到信号量。当第一个进程访问该文件时,它将信号量的值减去1,然后成功。信号量的值现在为0,进程可以继续执行和访问数据文件。但是,如果另一个进程也想要访问该文件,它还会将信号量的值减去1。因此,无法访问该文件,因为信号量的值变为-1。该进程将被挂起,直到第一个进程完成对数据文件的访问。当第一个进程完成对数据文件的访问时,它将增加信号量的值,使其再次变为1。现在,等待进程被唤醒,其信号量减1操作将成功。

[En]

Suppose you have many collaborative processes that are reading or writing records in a data file. You may want to strictly coordinate access to this file, so you use a semaphore with an initial value of 1, perform two operations on this semaphore, first test and subtract 1 from the semaphore, and then test and add 1 to the semaphore. When the first process accesses the file, it subtracts the value of the semaphore by 1 and succeeds. The value of the semaphore is now 0, and the process can continue to execute and access the data file. However, if another process also wants to access this file, it also subtracts the value of the semaphore by 1. As a result, the file cannot be accessed because the value of the semaphore becomes-1. This process will be suspended until the first process finishes accessing the data file. When the first process finishes accessing the data file, it will increase the value of the semaphore so that it becomes 1 again. Now, the waiting process is awakened and its semaphore minus 1 operation will be successful.

消息队列

消息队列也称为报文队列,消息队列是随内核持续的,只有在内核重起或显示删除一个消息队列时,该消息队列才会真正删除 系统中记录消息队列的数据结构struct ipc_ids msg_ids位于内核中,系统中所有消息队列都可以在结构msg_ids中找到访问入口

消息队列其实就是一个消息的链表,每个消息队列有一个队列头,称为struct msg_queue,这个队列头描述了消息队列的key值,用户ID,组ID等信息,但它存于内核中而结构体struct msqid_ds能够返回或设置消息队列的信息,这个结构体位于用户空间中,与msg_queue结构相似消息队列允许一个或多个进程向它写入或读取消息,消息队列是消息的链表。

消息按消息类型访问,流程必须指定消息类型才能读取消息。同样,在将消息写入消息队列时,必须提供消息类型。如果读取队列使用的消息类型为0,则读取队列中的第一条消息。

[En]

The message is accessed by message type, and the process must specify the message type to read the message. Similarly, when writing a message to the message queue, the message type must be given. If the message type used by the read queue is 0, the first message in the queue is read.

内核空间的结构体msg_queue描述了对应key值消息队列的情况,而对应于用户空间的msqid_ds这个结构体,因此,可以操作msgid_ds这个结构体来操作消息队列。

共享内存

共享内存是在同一台计算机上运行的进程之间进行通信的最快方式,因为不需要在不同的进程之间复制数据。通常,共享内存区由一个进程创建,其他进程对该内存区进行读写。共享内存通常与其他通信机制(如信号量)相结合,以实现进程之间的同步和互斥。

[En]

Shared memory is the fastest way to communicate between processes running on the same machine because data does not need to be copied between different processes. Usually a shared memory area is created by one process, and the other processes read and write to this memory area. Shared memory is often combined with other communication mechanisms, such as semaphores, to achieve synchronization and mutual exclusion between processes.

PS:

系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值 。通常情况下,该id值通过ftok函数得到 。
ftok原型如下:

参数说明:

fname就时您指定的文档名 id是子序号。

返回值:

在一般的UNIX实现中,是将文档的索引节点号取出,前面加上子序号得到key_t的返回值

如指定文档的索引节点号为65538,换算成16进制为0x010002,而您指定的ID值为38,换算成16进制 为 0x26,则最后的key_t返回值为0x26010002。

(查询文档索引节点号的方法是: ls -i)

Original: https://www.cnblogs.com/biyeymyhjob/archive/2012/11/04/2753535.html
Author: as_
Title: Linux进程间通信之信号量(semaphore)、消息队列(Message Queue)和共享内存(Share Memory)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/10150/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

发表回复

登录后才能评论
免费咨询
免费咨询
扫码关注
扫码关注
联系站长

站长Johngo!

大数据和算法重度研究者!

持续产出大数据、算法、LeetCode干货,以及业界好资源!

2022012703491714

微信来撩,免费咨询:xiaozhu_tec

分享本页
返回顶部