linux 共享内存 可不可以不加锁呢? 系统有两个进程,一个负责写入,一个负责读取

linux 共享内存 可不可以不加锁呢? 系统有两个进程,一个负责写入,一个负责读取,第1张

Linux共享内存可以不用加锁,不过需要一种机制来标记共享内存的读写状态;也就是说要让两个进程知道:1)负责写入的进程,必须知道当前共享内存是否可以写入,上一次的写入内容是否有被负责读取的进程读走;2)负责读取的进程,必须知道当前共享内存是否需要读取,防止重复读取。一般的这种标记机制是通过以下方式来简单实现:1)通过读写锁来控制;2)共享内存上设置一个地方,专门存放当前共享内存的读写状态;

在 Linux 中设置共享内存的方法有很多种,下面是一种常用的方法:

使用shmget()函数创建一块共享内存,可以指定共享内存的大小和标识符。

使用shmat()函数将共享内存连接到进程的地址空间,返回指向共享内存的指针。

使用shmdt()函数断开与共享内存的连接。

使用shmctl()函数删除共享内存。

具体实现可以参考以下代码示例:

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdio.h>

int main() {

// 1. 创建共享内存

int shmid = shmget(IPC_PRIVATE, 100, 0666 | IPC_CREAT)

if (shmid <0) {

perror("shmget error")

return 1

}

// 2. 连接共享内存

void *shm = shmat(shmid, NULL, 0)

if (shm == (void *)-1) {

perror("shmat error")

return 1

}

// 使用共享内存

// ...

// 3. 断开连接

if (shmdt(shm) <0) {

perror("shmdt error")

return 1

}

// 4. 删除共享内存

if (shmctl(shmid, IPC_RMID, 0) <0) {

perror("shmctl error")

return 1

}

return 0

}

这是一个简单的示例,在这里我们创建了一个大小为100字节的共享内存,并使用shmget()、shmat()、shmdt()、shmctl()四个函数来创建、连接、断开连接、删除共享内存。

在实际应用中,我们需要根据需要来调整共享内存的大小,并在使用共享内存时进行相应的同步和互斥 *** 作来保证数据的安全性。

需要注意的是,在使用共享内存时,我们需要确保共享内存在进程全部退出后能够被释放,这可以通过在父进

程中删除共享内存来实现。另外在程序中也要考虑到异常处理,如果在程序运行过程中发生了异常,应该及时释放所占用的共享内存,以免造成资源浪费。

另外需要提醒的是,共享内存是一种高级的IPC(Inter-Process Communication)机制,使用时需要谨慎,避免出现数据竞争和死锁等问题。

进程间通信有一种[共享内存]方式,大家有没有想过,这种通信方式中如何解决数据竞争问题?我们可能自然而然的就会想到用锁。但我们平时使用的锁都是用于解决线程间数据竞争问题,貌似没有看到过它用在进程中,那怎么办?

关于进程间的通信方式估计大多数人都知道,这也是常见的面试八股文之一。

个人认为这种面试题没什么意义,无非就是答几个关键词而已,更深入的可能面试官和面试者都不太了解。

关于进程间通信方式我之前在【这篇文章】中有过介绍,感兴趣的可以移步去看哈。

进程间通信有一种[共享内存]方式,大家有没有想过,这种通信方式中如何解决数据竞争问题?

我们可能自然而然的就会想到用锁。但我们平时使用的锁都是用于解决线程间数据竞争问题,貌似没有看到过它用在进程中,那怎么办?

我找到了两种方法,信号量和互斥锁。

直接给大家贴代码吧,首先是信号量方式:

代码中的MEOW_DEFER,它内部的函数会在生命周期结束后触发。它的核心函数其实就是下面这四个:

具体含义大家应该看名字就知道,这里的重点就是sem_init中的pshared参数,该参数为1表示可在进程间共享,为0表示只在进程内部共享。

第二种方式是使用锁,即pthread_mutex_t,可是pthread_mutex不是用作线程间数据竞争的吗,怎么能用在进程间呢?

可以给它配置一个属性,示例代码如下:

它的默认属性是进程内私有,但是如果给它配置成PTHREAD_PROCESS_SHARED,它就可以用在进程间通信中。

相关视频推荐

360度无死角讲解进程管理,调度器的5种实现

Linux进程间通信-信号量、消息队列和共享内存

学习地址:C/C++Linux服务器开发/后台架构师【零声教育】-学习视频教程-腾讯课堂

需要C/C++ Linux服务器架构师学习资料加qun812855908获取(资料包括 C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg 等),免费分享

完整代码如下:

我想这两种方式应该可以满足我们日常开发过程中的大多数需求。

锁的方式介绍完之后,可能很多朋友自然就会想到原子变量,这块我也搜索了一下。但是也不太确定C++标准中的atomic是否在进程间通信中有作用,不过看样子boost中的atomic是可以用在进程间通信中的。

其实在研究这个问题的过程中,还找到了一些很多解决办法,包括:

Disabling Interrupts

Lock Variables

Strict Alternation

Peterson's Solution

The TSL Instruction

Sleep and Wakeup

Semaphores

Mutexes

Monitors

Message Passing

Barriers

这里就不过多介绍啦,大家感兴趣的可以自行查阅资料哈。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/5930883.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-08
下一篇2023-03-08

发表评论

登录后才能评论

评论列表(0条)

    保存