首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

linux 共享内存 互斥锁

Linux 共享内存与互斥锁基础概念

共享内存是一种进程间通信(IPC)机制,允许多个进程访问同一块物理内存区域。这种通信方式非常高效,因为数据不需要在进程之间复制,而是直接在内存中共享。

互斥锁(Mutex)是一种同步机制,用于保护共享资源不被多个进程同时访问,从而避免数据竞争和不一致性。

优势

  • 高效性:共享内存是最快的IPC方式之一,因为它避免了数据的复制。
  • 灵活性:可以用于任意类型的数据交换。
  • 互斥锁确保了数据的一致性和完整性,防止并发访问导致的问题。

类型

  • 匿名共享内存:不与文件系统中的任何文件关联。
  • 具名共享内存:通过一个文件名来标识,可以在不同的进程之间方便地共享。

应用场景

  • 多进程服务器:如Web服务器,多个进程需要访问相同的配置信息或缓存数据。
  • 实时系统:需要在严格的时间限制内完成数据交换的场景。
  • 图形处理:多个进程可能需要共享大量的图像数据。

示例代码

以下是一个简单的例子,展示了如何在Linux中使用共享内存和互斥锁:

代码语言:txt
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>

#define SHM_SIZE 1024

int shmid;
char *shmaddr;
pthread_mutex_t mutex;

void* process(void* arg) {
    int id = *(int*)arg;
    pthread_mutex_lock(&mutex);
    sprintf(shmaddr, "Data from process %d", id);
    printf("Process %d wrote to shared memory\n", id);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    key_t key = ftok("/tmp/shmfile", 65);
    shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
    shmaddr = shmat(shmid, NULL, 0);

    pthread_t threads[5];
    int thread_ids[5] = {1, 2, 3, 4, 5};

    pthread_mutex_init(&mutex, NULL);

    for(int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, process, &thread_ids[i]);
    }

    for(int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }

    printf("Final data in shared memory: %s\n", shmaddr);

    pthread_mutex_destroy(&mutex);
    shmdt(shmaddr);
    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}

遇到的问题及解决方法

问题:进程间同步失败,导致数据不一致。

原因:可能是由于互斥锁未正确初始化或使用不当。

解决方法

  1. 确保在使用互斥锁之前已经通过pthread_mutex_init进行了初始化。
  2. 检查所有对共享资源的访问是否都被互斥锁保护。
  3. 使用pthread_mutex_lockpthread_mutex_unlock正确地加锁和解锁。

通过上述方法,可以有效地管理和同步对共享内存的访问,确保系统的稳定性和数据的准确性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

linux读写锁_共享内存读写锁

读写锁其实还是一种锁,是给一段临界区代码加锁,但是此加锁是在进行写操作的时候才会互斥,而在进行读的时候是可以共享的进行访问临界区的 ps:读写锁本质上是一种自旋锁 二、为什么需要读写锁?...而读的机会却是非常多的,此公共数据的操作基本都是读,如果每次操作都给此段代码加锁,太浪费时间了而且也很浪费资源,降低程序的效率,因为读操作不会修改数据,只是做一些查询,所以在读的时候不用给此段代码加锁,可以共享的访问...,只有涉及到写的时候,互斥的访问就好了 三、读写锁的行为 读写之间是互斥的—–>读的时候写阻塞,写的时候读阻塞,而且读和写在竞争锁的时候,写会优先得到锁 四、自旋锁&挂起等待是锁?...1.一种交易场所(存放数据的地方):可以是变量、链表、数组或其他数据结构 2.两种角色:读操作和写操作 3.三种关系:(1)读和读之间没有关系 (2) 写和写之间是互斥关系...(3)读和写之间是同步互斥关系 ps:同步---->读和写在同时竞争锁的时候,写会优先的得到锁 互斥---->读的时候写阻塞,写的时候读阻塞 4.相关函数 (1)

6.2K11

独占锁(写锁)共享锁(读锁)互斥锁

独占锁:指该锁一次只能被一个线程所持有。对ReentrantLock和Synchronized而言都是独占锁 共享锁:指该锁可被多个线程所持有。...对ReentrantReadWriteLock其读锁是共享锁,其写锁是独占锁。 读锁的共享锁可保证并发读是非常高效的,读写,写读,写写的过程是互斥的。...使用方法 声明一个读写锁 如果需要独占锁则加从可重入读写锁里得到写锁 写锁demo 如果需要共享锁则加从可重入读写锁里得到读锁 读锁demo ReentrantReadWriteLock实现原理简单分析...ReentrantReadWriteLock 的核心是由一个基于AQS的同步器 Sync 构成,然后由其扩展出 ReadLock (共享锁), WriteLock (排它锁)所组成。...Sync是如何同时表示读锁与写锁?

1.4K30
  • 共享内存+互斥量实现 Linux 进程间通信

    一、共享内存简介     共享内存是进程间通信中高效方便的方式之一。...共享内存并未提供进程同步机制,使用共享内存完成进程间通信时,需要借助互斥量或者信号量来完成进程的同步。这里说一下互斥量与信号量的区别。...本文结合个人实际项目需求,采用互斥量实现进程间访问共享内存的互斥,即同一时刻只能允许一个进程对共享内存进行写操作,当然也可以用信号量来完成进程间的互斥,这里就不再赘述。...三、 使用互斥量完成父子进程对共享内存的互斥访问     在共享内存中申明互斥量pthread_mutex_t mutex,需要包含头文件。...salt[128][32];//最多128个,最长32字节 char re[32][256]; uint8 plainfile_num; pthread_mutex_t mutex;//读写共享内存互斥量

    2.3K30

    Linux线程互斥锁

    今天我们学习Linux线程互斥的话题。Linux同步和互斥是Linux线程学习的延伸。但这部分挺有难度的,请大家做好准备。那我们就正式开始了。...多个执行流进行安全访问的共享资源,叫做临界资源 我们把多个执行流中,访问临界资源的代码叫做临界区,临界区往往是线程代码很小的一部分。 想让多个线程串行访问共享资源的方式叫做互斥。...锁只规定互斥访问,没有规定谁优先访问。 锁就是让多个线程公平竞争的结果,强者胜出嘛。 关于互斥锁的理解 所有的执行流都可以访问这一把锁,所以锁是一个共享资源。...为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性 。...对互斥锁的简单封装 相信大家对互斥锁都有了充分的了解。接下来,我们就实现一下对互斥锁的简单封装。

    9410

    Java并发编程:AQS的互斥锁与共享锁

    刚开始内存中i=0,线程一读取后将i加5。修改完后线程二才读取内存中的i并将其加6,最终i=11。而下面的情况则不同,线程二在线程一还没修改完就读取内存中i,此时导致最终的结果为i=6。 ?...if(尝试释放锁成功){ 唤醒后续节点包含的线程 } 05 共享锁 共享锁是指该锁可以由多个线程所持有,多个线程都能同时获得该锁,而不必等到持有锁的线程释放该锁。...比如一般我们所说的读锁就是共享锁,一个共享数据是可以被多个线程去读取的,只要它们都不改变共享数据就不会有数据竞争问题。...获取共享锁和释放共享锁分别对应acquireShared方法和releaseShared方法。获取共享锁的主要逻辑为:先尝试获取锁,成功则往下执行,否则把线程放到等待队列中并可能将线程挂起。...释放共享锁的主要逻辑为:唤醒等待队列中一个或多个线程去尝试获取锁。在AQS中可以用以下伪代码表示共享锁的获取与释放。 - END -

    1.3K40

    Java 并发编程:AQS 的互斥锁与共享锁

    刚开始内存中i=0,线程一读取后将i加5。修改完后线程二才读取内存中的i并将其加6,最终i=11。而下面的情况则不同,线程二在线程一还没修改完就读取内存中i,此时导致最终的结果为i=6。...if(尝试释放锁成功){ 唤醒后续节点包含的线程 } 共享锁 获取共享锁和释放共享锁分别对应acquireShared方法和releaseShared方法。...获取共享锁的主要逻辑为:先尝试获取锁,成功则往下执行,否则把线程放到等待队列中并可能将线程挂起。释放共享锁的主要逻辑为:唤醒等待队列中一个或多个线程去尝试获取锁。...在AQS中可以用以下伪代码表示共享锁的获取与释放。...并发编程:Java 序列化的工作机制 Java并发编程:并发中死锁的形成条件及处理 Java并发编程:进程、线程、并行与并发 Java并发编程:任务执行器Executor接口 Java 并发编程:AQS 的互斥锁与共享锁

    60350

    linux 编程常用的进程间通信方式:互斥锁和条件变量、共享内存和信号量

    本文介绍常见的进程间通信方式,分为互斥锁和条件变量,共享内存和信号量两部分,并分别给出样例使用方式和运行结果: 一、互斥锁和条件变量 1....生产者和消费者使用互斥锁和条件变量通信 在单个进程中创建多个线程,分为生产者线程和消费者线程,生产者和消费者使用同一块内存区。...生产者向内存区写入数据,同时修改head和tail,消费者从内存区读取数据,也修改head和tail。 对于内存区不允许消费者和生产者同时访问,因此使用pthread_mutex_t进行互斥锁保护。...producer中让用户输入几个整数,并将输入的整数保存到共享内存中,然后consumer从共享内存中读取整数相加产生结果。这里的信号量只设定为1,起到了互斥锁的作用。...实际运行结果如下: image.png 使用ipcs命令可以查看到我们创建的共享内存和信号量: image.png 三、在使用锁时,需要注意不要产生死锁 1.

    2.5K80

    Linux内核中的各种锁:信号量互斥锁读写锁原子锁自旋锁内存屏障等

    使用实例如下: #include linux/spinlock.h> // 定义自旋锁 spinlock_t my_lock; void my_function(void) { spin_lock...(&my_lock); // 访问共享资源的操作 spin_unlock(&my_lock); } 互斥锁中,要是当前线程没拿到锁,就会出让CPU;而自旋锁中,要是当前线程没有拿到锁,当前线程在...但是互斥锁不是,它的目的就是只让一个线程进入临界区,其余线程没拿到锁,就只能阻塞等待。线程互斥的进入临界区,这就是互斥锁名字由来。...另外提一下std::timed_mutex睡眠锁,它和互斥锁的区别是: 互斥锁中,没拿到锁的线程就一直阻塞等待,而睡眠锁则是设置一定的睡眠时间比如2s,线程睡眠2s,如果过了之后还没拿到锁,那就放弃拿锁...它允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这可以提高并发性能,因为读操作通常比写操作频繁得多。读写锁这种就属于高阶锁了,它的实现就可以用自旋锁。

    1.6K20

    Linux C 编程——互斥锁mutex

    ,在Linux编程中,线程同步的处理方法包括:信号量,互斥锁和条件变量。...2、互斥锁 互斥锁是通过锁的机制来实现线程间的同步问题。...互斥锁的基本流程为: 初始化一个互斥锁:pthread_mutex_init()函数 加锁:pthread_mutex_lock()函数或者pthread_mutex_trylock()函数 对共享资源的操作...()函数的过程略有不同: 当使用pthread_mutex_lock()函数进行加锁时,若此时已经被锁,则尝试加锁的线程会被阻塞,直到互斥锁被其他线程释放,当pthread_mutex_lock()函数有返回值时...同时,解锁的过程中,也需要满足两个条件: 解锁前,互斥锁必须处于锁定状态; 必须由加锁的线程进行解锁。 当互斥锁使用完成后,必须进行清除。

    5.3K110

    go 互斥锁和读写互斥锁

    互斥锁 互斥锁是一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源。Go语言中使用sync包的Mutex类型来实现互斥锁。...}() } // 等待所有goroutine执行完毕 wg.Wait() // 输出x(10000) fmt.Println(x) } 读写互斥锁...互斥锁是完全互斥的,但是有很多实际的场景下是读多写少的,当并发的去读取一个资源不涉及资源修改的时候是没有必要加锁的,这种场景下使用读写锁是更好的一种选择。...读写锁分为两种:读锁和写锁。...当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待

    23030

    Golang中互斥锁和读写互斥锁

    互斥锁         在Golang中,互斥锁(Mutex)是一种基本的同步原语,用于实现对共享资源的互斥访问。...互斥锁通过在代码中标记临界区来控制对共享资源的访问,从而保证同一时间只有一个 goroutine 可以访问共享资源,避免了并发访问时的数据竞争和不一致性问题。         ...一般来说,在使用互斥锁时,需要先通过 Lock 方法锁定共享资源,访问共享资源,然后再通过 Unlock 方法解锁共享资源,让其他 goroutine 可以访问。...读写互斥锁         Go语言中的读写互斥锁(RWMutex)是一种特殊类型的互斥锁,它允许多个协程同时读取某个共享资源,但在写入时必须互斥,只能有一个协程进行写操作。...在写入共享资源时,需要调用Lock()方法加写锁,在写入完成后,需要调用Unlock()方法释放写锁。当有写锁或读写锁时,不能再加读锁或写锁,直到已经释放了所有锁。

    31630

    LiteOS内核教程05 | 互斥锁(共享资源保护)

    LiteOS的互斥锁 1.1. 互斥锁 在多任务环境下,往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。...互斥锁(mutex)又称互斥型信号量,是一种特殊的二值信号量,用于实现对共享资源的独占式处理。另外,Huawei LiteOS提供的互斥锁通过优先级继承算法,解决了优先级翻转问题。 1.2....互斥锁的使用方式 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。 互斥锁怎样来避免这种冲突呢? 在任意时刻,互斥锁的状态只有两种:开锁和闭锁。...互斥锁的使用场景 互斥锁可以提供任务之间的互斥机制,用来防止两个任务在同一时刻访问相同的共享资源。 除此之外,互斥锁还可以被用于防止多任务同步时造成优先级翻转的问题。 2....,操作完毕解锁,然后主动挂起,task1获取到互斥锁,对共享资源进行另一个操作,操作完毕解锁,在task1操作的时候,task2早已挂起完毕,但是获取不到互斥锁,所以挂起等待,在task1解锁后,堵塞的

    1.1K20

    初识Linux · 共享内存

    我们通过这个图,引出我们今日的话题: 在Linux中,万物皆是文件的概念已经深深的刻入到了我们的大脑里面,在文件系统里面我们介绍了进程,介绍了地址空间,介绍了页表,介绍了物理内存之间的映射关系,知道了代码和数据的地址通过页表...那么新的问题来了:是否存在多个共享内存?如果存在多个共享内存,那么OS是否有必要对共享内存进行管理?如果要实施管理,OS是如何进行管理的?...在Linux源码里面是有共享内存对应的结构体的,这里因为不介绍,所以不放出对应的源码了,肯定就有人说了,怎么又又又是结构体?...因为Linux就是C语言写的呀,并且,C语言想要对某个对象管理,结构体不是最好的选择吗? 所以我们得出一个结论,共享内存 = 共享内存的数据 + 共享内存的属性!!...对于第一种模式,IPC_CREAT,代表的是如果创建的共享内存不存在,就创建,如果存在共享内存,就获取该共享内存并返回,说白了就是总能够获取一个共享内存,但是不一定是全新的。

    8610

    互斥锁-读写锁-条件锁

    一,使用互斥锁 1,初始化互斥量 不能拷贝互斥量变量,但可以拷贝指向互斥量的指针,这样就可以使多个函数或线程共享互斥量来实现同步。上面动态申请的互斥量需要动态的撤销。...二,使用读写锁 通过读写锁,可以对受保护的共享资源进行并发读取和独占写入。读写锁是可以在读取或写入模式下锁定的单一实体。要修改资源,线程必须首先获取互斥写锁。...初始化和销毁: 同互斥量一样, 在释放读写锁占用的内存之前, 需要先通过pthread_rwlock_destroy对读写锁进行清理工作, 释放由init分配的资源. 2.加锁和解锁 三,条件变量...假如某个线程需要等待系统处于某种状态下才能继续执行,Linux为了解决这种问题引入了条件变量这种线程同步对象,条件变量是用来通知共享数据状态信息的,等待条件变量总是返回锁住的互斥量,条件变量是与互斥量相关...、也与互斥量保护的共享数据相关的信号机制。

    82410

    共享内存无锁队列的实现

    作者:范健 导语: 共享内存无锁队列是老调重弹了,相关的实现网上都能找到很多。但看了公司内外的很多实现,都有不少的问题,于是自己做了重新实现。...主要是考虑了一些异常情况加强健壮性,并且考虑了C++11的内存模型。 为什么需要共享内存无锁队列?...又因为业务模块可能是多线程模式也可能是多进程模式,所以队列应该是在共享内存中。 简单的做法是,对队列的读写都加锁,但这样无疑会导致高并发下性能瓶颈就在这把锁上。所以我们需要无锁队列。...共享内存 另外一个值得一提的点是,共享内存我使用mmap,而非shmget。因为担心一台机器上部署的程序太多,可能出现共享内存key冲突的情况。...使用共享内存等共享资源时,更要想到,这资源不是我独占的,万一被有意或无意的篡改了数据该怎么办?能否尽量避免被别人篡改?如果被篡改,是否有发现和恢复机制?

    12.3K31

    自旋锁和互斥锁区别在哪_互斥锁的实现

    A,B两个人合租一套房子,共用一个厕所,那么这个厕所就是共享资源,且在任一时刻最多只能有一个人在使用。...要调整运行级别 因为另一个CPU可能在死循环不干活 自己必须快点执行完 要快点执行完 就必须保证自己的原子性 因此提高权限关闭中断是必须的 其实windows的自旋锁机制还是很简单的了 linux...更复杂 linux提供了更多自旋锁操作方式 尤其是对中断中使用自旋锁的情况 当然一般是不提倡中断中使用自旋锁的 所以,自旋锁一般用用多核的服务器。...自旋锁(Spin lock) 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名...其作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠,所以自旋锁的效率远 高于互斥锁。

    1K30

    嵌入式Linux:线程同步(互斥锁)

    Linux线程的互斥锁(mutex)是用于保护共享资源的同步机制,确保在多线程环境中,多个线程不会同时访问或修改同一个资源,从而避免数据竞争或不一致的问题。...当一个线程想要访问受保护的共享资源时,它首先必须尝试锁定互斥锁,如果锁已经被其他线程持有,则它必须等待,直到锁被释放。 当线程完成对资源的操作后,它需要解锁互斥锁,以便其他线程可以访问该资源。...在Linux下,线程互斥锁主要通过POSIX线程库(pthread)来实现,通常的步骤包括: 初始化互斥锁:使用pthread_mutex_init()或直接用静态初始化PTHREAD_MUTEX_INITIALIZER...锁定互斥锁:在线程需要访问共享资源前,使用pthread_mutex_lock()锁定。 访问共享资源:执行需要对共享资源的操作。...EBUSY:互斥锁已经被初始化。 ENOMEM:内存不足,无法分配资源。 2、互斥锁加锁与解锁 2.1、互斥锁加锁 pthread_mutex_lock() 用于对互斥锁加锁。

    4300
    领券